00001 #include "TEpicsProc.h"
00002
00003 #include "TTimeStamp.h"
00004 #include "TROOT.h"
00005 #include "TSystem.h"
00006 #include "TDatime.h"
00007 #include "TCanvas.h"
00008
00009 #include "TGo4Log.h"
00010
00011
00012 #include "roc/Board.h"
00013
00014 #define CBM_EPIX_SUBID roc::proc_EPICS
00015
00016
00017
00018
00019 TEpicsProc::TEpicsProc() :
00020 TCBMBeamtimeProc(),
00021 fPar(0),
00022 fOutputEvent(0)
00023 {
00024 }
00025
00026 TEpicsProc::TEpicsProc(const char* name) :
00027 TCBMBeamtimeProc(name),
00028 fPar(0),
00029 fOutputEvent(0)
00030 {
00031 TGo4Log::Info("TEpicsProc: Create instance %s", name);
00032
00033 fPar = (TEpicsParam*) MakeParameter("EPICSPar", "TEpicsParam", "set_EPICSPar.C");
00034
00035 for(int nl=0; nl<CBM_EPIX_NUMHIS_LONG; ++nl)
00036 CreateHist(fPar->LongName(nl));
00037
00038 for(int dl=0; dl<CBM_EPIX_NUMHIS_DOUBLE; ++dl)
00039 CreateHist(fPar->DoubleName(dl));
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 }
00073
00074 TEpicsProc::~TEpicsProc()
00075 {
00076 }
00077
00078 TEpicsProc::VariableHist* TEpicsProc::CreateHist(const char* varname)
00079 {
00080 if ((varname==0) || (strlen(varname)==0)) return 0;
00081
00082 const char* dirname = "EPICS";
00083 Double_t range = CBM_EPIX_STATRANGE;
00084 Int_t bins = 2*CBM_EPIX_STATRANGE;
00085
00086 TString obname;
00087 TString obtitle;
00088
00089 VariableHist dummy;
00090 all_hists.push_back(dummy);
00091
00092 obname.Form("%s/Statistics/Stat_%s", dirname, varname);
00093 obtitle.Form("EPICS variable %s statistics", varname);
00094 all_hists.back().fStat = MakeTH1('I', obname.Data(), obtitle.Data(), bins, -range, range);
00095 obname.Form("%s/Trending/Trend_%s",dirname, varname);
00096 obtitle.Form("EPICS variable %s trending", varname);
00097 all_hists.back().fTrend = MakeTH1('I', obname.Data(), obtitle.Data(), CBM_EPIX_TRENDSIZE, 0, CBM_EPIX_TRENDSIZE);
00098
00099 all_hists.back().fGraph = MakeTimeGraph(varname, dirname);
00100
00101 return & all_hists.back();
00102 }
00103
00104
00105 void TEpicsProc::InitEvent(TGo4EventElement* outevnt)
00106 {
00107 TCBMBeamtimeEvent* btevent = dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00108 if (btevent) {
00109
00110
00111 if (fOutputEvent == 0)
00112 fOutputEvent = dynamic_cast<TEpicsEvent*>(btevent->GetSubEvent("EPICS"));
00113 } else {
00114 fOutputEvent= dynamic_cast<TEpicsEvent*>(outevnt);
00115 }
00116 if (fOutputEvent == 0) {
00117 GO4_STOP_ANALYSIS_MESSAGE("TEpicsProc: Fatal error: output event is not a TEpicsEvent!!! STOP GO4");
00118 }
00119 }
00120
00121
00122 void TEpicsProc::ProcessSubevent(TGo4MbsSubEvent* psubevt)
00123 {
00124 #if __GO4BUILDVERSION__ > 40500
00125 Bool_t oldevent=IsKeepInputEvent();
00126 SetKeepInputEvent(kFALSE);
00127 if(oldevent) return;
00128 #endif
00129 if (psubevt->GetProcid() != CBM_EPIX_SUBID) return;
00130
00131 fOutputEvent->ResetData();
00132 Int_t* pdata = psubevt->GetDataField();
00133 Int_t* theEnd = psubevt->GetDataField() + psubevt->GetIntLen();
00134
00135 fOutputEvent->fEventId = *pdata++;
00136 if (fPar->fVerbose)
00137 printf("Found EPICS event id %u\n", fOutputEvent->fEventId);
00138
00139
00140 fOutputEvent->fUTimeSeconds = (UInt_t) *pdata++;
00141 if (fPar->fVerbose)
00142 printf("Found EPICS timestring: %s\n", fOutputEvent->GetUpdateTimeString());
00143
00144
00145
00146 Long64_t* plong = (Long64_t*) pdata;
00147
00148 int numlong= *plong++;
00149 if (fPar->fVerbose)
00150 printf("Num long: %d\n", numlong);
00151
00152 for (int i = 0; i < numlong; ++i) {
00153 Long64_t val = *plong++;
00154 if (fPar->fVerbose)
00155 printf(" Long[%d] = %lld\n", i, val);
00156 fOutputEvent->fLongRecords.push_back(val);
00157 }
00158
00159
00160
00161 int numdub = *plong++;
00162 if (fPar->fVerbose)
00163 printf("Num double: %d\n", numdub);
00164
00165 Double_t* pdouble= (Double_t*) (plong);
00166 for (int i = 0; i < numdub; ++i) {
00167 #ifdef CBM_EPIX_useDOUBLES
00168 Double_t val = *pdouble++;
00169 Long64_t valint = val;
00170 plong++;
00171
00172 #else
00173 Long64_t valint = *plong++;
00174 Double_t val = (Double_t) (valint) / CBM_EPIX_DOUBLESCALE;
00175 #endif
00176
00177 if (fPar->fVerbose)
00178 printf(" Double[%d] = int:%lld float:%f\n", i, valint, val);
00179
00180 fOutputEvent->fDoubleRecords.push_back(val);
00181 }
00182 pdata = (Int_t*) plong;
00183
00184 if(pdata<theEnd) {
00185 unsigned rest = (char*)theEnd - (char*)pdata;
00186 if (fPar->fVerbose)
00187 printf("Found description at mbs event end, pdata:0x%p end: 0x%p, rest=0x%x\n",
00188 pdata, theEnd, rest);
00189
00190 fOutputEvent->UpdateRecordNames((const char*) pdata, rest);
00191 }
00192
00193 if (!fOutputEvent->CheckConsistent(true)) {
00194 fOutputEvent->SetValid(kFALSE);
00195 } else {
00196 fOutputEvent->SetValid(kTRUE);
00197 }
00198 }
00199
00200 TEpicsProc::VariableHist* TEpicsProc::FindVariable(const char* name)
00201 {
00202 if ((name==0) || (strlen(name)==0)) return 0;
00203 for (unsigned n=0;n<all_hists.size();n++)
00204 if (all_hists[n].IsName(name)) return & all_hists[n];
00205
00206 return 0;
00207 }
00208
00209
00210 void TEpicsProc::FinalizeEvent()
00211 {
00212
00213 if (!fOutputEvent->IsValid()) return;
00214
00215 if(fPar->fVerbose)
00216 fOutputEvent->PrintEvent();
00217
00218 if (fPar->fAutoFill) {
00219
00220
00221
00222 for (unsigned n=0;n<fOutputEvent->GetNumLongs();n++) {
00223
00224 const char* varname = fOutputEvent->GetLongName(n).c_str();
00225 VariableHist* hist = FindVariable(varname);
00226 if (hist==0) hist = CreateHist(varname);
00227
00228 UpdateHist(hist, fOutputEvent->GetLong(n), varname);
00229 }
00230
00231 for (unsigned n=0;n<fOutputEvent->GetNumDoubles();n++) {
00232
00233 const char* varname = fOutputEvent->GetDoubleName(n).c_str();
00234
00235 VariableHist* hist = FindVariable(varname);
00236 if (hist==0) hist = CreateHist(varname);
00237
00238 UpdateHist(hist, fOutputEvent->GetDouble(n), varname);
00239 }
00240
00241 } else {
00242
00243 for (int nl = 0; nl < CBM_EPIX_NUMHIS_LONG; ++nl) {
00244 const char* varname = fPar->LongName(nl);
00245 VariableHist* hist = FindVariable(varname);
00246 if (hist)
00247 UpdateHist(hist, fOutputEvent->GetLong(varname), varname);
00248 }
00249
00250 for (int dl = 0; dl < CBM_EPIX_NUMHIS_DOUBLE; ++dl) {
00251 const char* varname = fPar->DoubleName(dl);
00252 VariableHist* hist = FindVariable(varname);
00253 if (varname)
00254 UpdateHist(hist, fOutputEvent->GetDouble(varname), varname);
00255 }
00256 }
00257 }
00258
00259
00260 void TEpicsProc::UpdateTrending(TH1* histo, Double_t val, time_t time)
00261 {
00262
00263 IncTrending( histo, val, kTRUE);
00264 }
00265
00266
00267 void TEpicsProc::IncTrending( TH1 * histo, Double_t value, bool forwards )
00268 {
00269 if(histo==0) return;
00270 int bins = histo->GetNbinsX();
00271
00272 int j = forwards ? bins : 0;
00273 int dj = forwards ? -1 : +1;
00274 for(int i=0;i<bins;i++) {
00275 j = forwards ? bins-i : i;
00276 Double_t oldval = histo->GetBinContent(j+dj);
00277 histo->SetBinContent(j,oldval);
00278 }
00279 histo->SetBinContent(j+dj,value);
00280 }
00281
00282 TGraph* TEpicsProc::MakeTimeGraph(const TString& name, const TString& dir)
00283 {
00284 TString fullname=dir+"/"+name;
00285
00286 TGraph* gr=dynamic_cast<TGraph*>(GetObject(fullname));
00287 if(gr==0) {
00288 gr=new TGraph();
00289 gr->SetName(name);
00290 gr->SetMarkerStyle(33);
00291 TCanvas* c1 = new TCanvas("c1","c1",3);
00292 gr->Draw("A");
00293 delete c1;
00294 gr->GetXaxis()->SetTimeDisplay(1);
00295 gr->GetXaxis()->SetNdivisions(-503);
00296 gr->GetXaxis()->SetTimeFormat("%H:%M:%S");
00297 gr->GetXaxis()->SetTimeOffset(0,"gmt");
00298 AddObject(gr,dir.Data());
00299 }
00300 gr->GetXaxis()->SetTimeOffset(0,"gmt");
00301 return gr;
00302 }
00303
00304
00305 void TEpicsProc::UpdateTimeGraph(TGraph* gr, Double_t value, time_t time)
00306 {
00307 TDatime offs(1995,1,1,0,0,0);
00308 TDatime dt(time, kFALSE);
00309 Int_t npoints = gr->GetN();
00310 gr->SetPoint(npoints,(dt.Convert() - offs.Convert()),value);
00311 }
00312
00313 void TEpicsProc::UpdateHist(VariableHist* hst, double val, const char* varname)
00314 {
00315 if ((varname==0) || (hst==0)) return;
00316
00317 hst->fStat->Fill(val);
00318 hst->fStat->SetTitle(Form("Statistics of %s at %s", varname, fOutputEvent->GetUpdateTimeString()));
00319 UpdateTrending(hst->fTrend, val ,fOutputEvent->GetUpdateTimeSeconds());
00320 hst->fTrend->SetTitle(Form("Trending of %s at %s", varname, fOutputEvent->GetUpdateTimeString()));
00321 UpdateTimeGraph(hst->fGraph, val, fOutputEvent->GetUpdateTimeSeconds());
00322 hst->fGraph->SetTitle(Form("Timegraph of %s", varname));
00323 }