• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

onlinemonitor/epicsmonitor/TEpicsProc.cxx (r4864/r4366)

Go to the documentation of this file.
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 // still need this for subevent types:
00012 #include "roc/Board.h"
00013 
00014 #define CBM_EPIX_SUBID roc::proc_EPICS
00015 
00016 // note: this id was used in cosy December 2010 beamtime.
00017 //#define CBM_EPIX_SUBID 0x08
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    // picture not yet supports time display for tgraph axis.
00042    //   if (GetPicture("EPICS/TimeGraphsLong")==0) {
00043    //      TGo4Picture* pic = new TGo4Picture("TimeGraphsLong", "EPICS long pv time graphs");
00044    //      int numy = 4;
00045    //      int numx = (CBM_EPIX_NUMHIS_LONG-1) / numy;
00046    //      if (numx*numy < (CBM_EPIX_NUMHIS_LONG - 1)) numx++;
00047    //      pic->SetDivision(numy, numx);
00048    //
00049    //      for (UInt_t sid = 1; sid < CBM_EPIX_NUMHIS_LONG; sid++) {
00050    //        int nx = (sid-1) / numy;
00051    //        int ny = (sid-1) % numy;
00052    //        pic->Pic(ny, nx)->AddGraph(fGraphLong[sid]);
00053    //      }
00054    //      AddPicture(pic,"EPICS");
00055    //    }
00056    //
00057    //   if (GetPicture("EPICS/TimeGraphsDouble")==0) {
00058    //         TGo4Picture* pic = new TGo4Picture("TimeGraphsDouble", "EPICS double pv time graphs");
00059    //         int numy = 4;
00060    //         int numx = (CBM_EPIX_NUMHIS_DOUBLE) / numy;
00061    //         if (numx*numy < (CBM_EPIX_NUMHIS_DOUBLE)) numx++;
00062    //         pic->SetDivision(numy, numx);
00063    //
00064    //         for (UInt_t sid = 0; sid < CBM_EPIX_NUMHIS_DOUBLE; sid++) {
00065    //           int nx = (sid) / numy;
00066    //           int ny = (sid) % numy;
00067    //           pic->Pic(ny, nx)->AddGraph(fGraphDouble[sid]);
00068    //
00069    //         }
00070    //         AddPicture(pic,"EPICS");
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       // since output event object is never discarded within processor lifetime,
00110       // we just search for subevent by name once to speed up processing
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); // need this to reset our flag in case rocproc had requested it.
00127    if(oldevent) return; // ignore this subevent if we already had it
00128 #endif
00129    if (psubevt->GetProcid() != CBM_EPIX_SUBID) return;
00130 
00131    fOutputEvent->ResetData(); // Clear() will not erase old values, do this now
00132    Int_t* pdata = psubevt->GetDataField();
00133    Int_t* theEnd = psubevt->GetDataField() + psubevt->GetIntLen();
00134    //first payload: event id number
00135    fOutputEvent->fEventId = *pdata++;
00136    if (fPar->fVerbose)
00137       printf("Found EPICS event id %u\n", fOutputEvent->fEventId);
00138 
00139    // secondly get dabc record time expression
00140    fOutputEvent->fUTimeSeconds = (UInt_t) *pdata++;
00141    if (fPar->fVerbose)
00142       printf("Found EPICS timestring: %s\n", fOutputEvent->GetUpdateTimeString());
00143 
00144    //int numlong = *pdata++;
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    //plong= (Long64_t*) pdata;
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    // get header with number of double records
00160    //int numdub = *pdata++;
00161    int numdub = *plong++;
00162    if (fPar->fVerbose)
00163       printf("Num double: %d\n", numdub);
00164    //plong= (Long64_t*) pdata;
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       // cout << "double("<<i<<")=" << val << endl;
00172 #else
00173       Long64_t valint = *plong++;
00174       Double_t val = (Double_t) (valint) / CBM_EPIX_DOUBLESCALE; // workaround to avoid number format tricks
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    // process optional additional variable names and update names map
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); // mark as newly updated
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    // skip not updated events
00213    if (!fOutputEvent->IsValid()) return;
00214 
00215    if(fPar->fVerbose)
00216       fOutputEvent->PrintEvent();
00217 
00218    if (fPar->fAutoFill) {
00219 
00220       // automatically extend parameter with variables from output event
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    // first test: just use simple binwise trending
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    //bool forwards=true;
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    //cout <<"fullname "<<fullname << endl;
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");// dummy create axis:
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); // substract begin of root time  from unix epoch
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 }

Generated on Tue Dec 10 2013 04:52:23 for ROCsoft by  doxygen 1.7.1