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

beamtime/cosy-jan12/go4/TMbsCrateProc.cxx (r4864/r2543)

Go to the documentation of this file.
00001 #include "TMbsCrateProc.h"
00002 
00003 #include <stdlib.h>
00004 
00005 #include "TTimeStamp.h"
00006 #include "TSystem.h"
00007 #include "TROOT.h"
00008 #include "TGo4Log.h"
00009 
00010 // still need this for subevent types:
00011 #include "roc/Message.h"
00012 #include "roc/Board.h"
00013 
00014 #include "../mbs/cbmvme.h"
00015 
00016 const uint32_t vme_setup[MAX__N_MOD*6] = VME__MODULES;
00017 
00018 uint64_t vme_tags[MAX__N_MOD];
00019 
00020 #define L1182_DEBUG 0
00021 
00022 
00023 TMbsCrateProc::TMbsCrateProc(const char* name) : TCBMBeamtimeProc(name),fOutputEvent(0)
00024 {
00025    TGo4Log::Info("TMbsCrateProc: Create instance %s", name);
00026 
00027    TString obname, obtitle;   
00028 
00029    // v1290 histograms
00030 
00031    for (int n=0;n<MAX_1290;n++)
00032       fTDC[n].MakeHistos(this, Form("TDC%d",n));
00033 
00034    for (int n=0;n<MAX_965;n++)
00035       for (int ch=0;ch<MQDC_t::NumChan;ch++) {
00036          obname.Form("QDC%d/Charge%d_%d",n,n,ch);
00037          obtitle.Form("Chgarge of QDC %d channel %d",n,ch);
00038          fQdc_Charge[n][ch] = MakeTH1('I',obname.Data(),obtitle.Data(),4096,1,4096,"charge");
00039       }
00040 
00041    for (int n=0;n<MAX_FPGA_TDC;n++)
00042       for (int ch=0;ch<MAX_FPGA_TDC_Channel;ch++) {
00043          obname.Form("FPGA_TDC%d/FPGA_TDC%d_Ch%d", n, n, ch);
00044          obtitle.Form("Fine counter of TDC%d channel %d", n, ch);
00045          fFPGA_Ch[n][ch] = MakeTH1('I', obname.Data(), obtitle.Data(), 0x800, 0, 0x800, "cnt");
00046       }
00047 
00048    // 1182 histograms
00049 
00050    for (int n=0;n<MAX_1182;n++)
00051       for (int ch=0;ch<NUM_1182_CH;ch++) {
00052          obname.Form("118%d/118%d_channel%d", n+2, n+2, ch);
00053          obtitle.Form("118%d Channel %d", n+2, ch);
00054          f1182h[n][ch] = MakeTH1('I', obname.Data(), obtitle.Data(), 1024, 0, 4096.);
00055       }
00056 
00057 
00058    // QFW histograms
00059    fQFWcnt = MakeTH1('I', "QFW/QFWcnt", "Counts in QFW channels", 4, 0, 4, "cnt");
00060    fQFWerr = MakeTH1('I', "QFW/QFWerr", "Error counts in QFW channels", 4, 0, 4, "err");
00061 
00062    fQFWInfo = new TLatex(0.5,0.5,"-- demo text --");
00063    fQFWInfo->SetName("QFWInfo");
00064    fQFWInfo->SetNDC();
00065    AddObject(fQFWInfo);
00066 
00067    for (int n=0;n<MAX__N_MOD;n++) {
00068       if (n != (int)vme_setup[n*6]) {
00069          TGo4Log::Error("Wrong setup in cbmvme.h file in row %d",n);
00070          exit(1);
00071       }
00072 
00073       vme_tags[n] = (((uint64_t) vme_setup[n*6+5]) << 32) | vme_setup[n*6+4];
00074 
00075       if ((n>0) && (vme_tags[n]==0)) {
00076          TGo4Log::Error("Wrong setup in cbmvme.h - zero tag in row %d", n);
00077          exit(1);
00078       }
00079    }
00080 
00081    printf("TMbsCrateProc - Histograms created \n");
00082    fflush( stdout);
00083 }
00084 
00085 TMbsCrateProc::~TMbsCrateProc()
00086 {
00087 }
00088 
00089 void TMbsCrateProc::InitEvent(TGo4EventElement* outevnt)
00090 {
00091    TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00092    if(btevent)
00093    {
00094       // since output event object is never discarded within processor lifetime,
00095       // we just search for subevent by name once to speed up processing
00096       if(fOutputEvent==0)
00097          fOutputEvent=dynamic_cast<TMbsCrateEvent*>(btevent->GetSubEvent("MBSCRATE"));
00098    }
00099    else
00100    {
00101 
00102       fOutputEvent= dynamic_cast<TMbsCrateEvent*>(outevnt);
00103    }
00104    if(fOutputEvent==0) {
00105       GO4_STOP_ANALYSIS_MESSAGE("**** TMbsCrateProc: Fatal error: output event is not a TMbsCrateEvent!!! STOP GO4");
00106    }
00107 }
00108 
00109 void TMbsCrateProc::ProcessSubevent(TGo4MbsSubEvent* subevt)
00110 {
00111 // uncomment this to test with previous beamtime lmds:
00112 //   if (subevt->GetProcid() == roc::proc_CERN_Oct11) {
00113 // comment this to test with previous beamtime lmds:
00114    if (subevt->GetProcid() == roc::proc_COSY_Nov11) {
00115       // MBS data from COSY beamtime, November 11
00116       // subevt->GetControl() == 9 from Master MBS, subevt->GetControl() == 10 from Slave MBS
00117 
00118       fOutputEvent->SetValid(kTRUE);
00119 
00120       Int_t *pdata = subevt->GetDataField();
00121       UInt_t lwords = subevt->GetIntLen();
00122 
00123       // printf("CERN subevent Control %u TOTALLEN = %u\n", subevt->GetControl(), lwords);
00124 
00125       Int_t* tagpos[MAX__N_MOD];
00126       Int_t taglen[MAX__N_MOD];
00127 
00128       for (int n=0;n<MAX__N_MOD;n++) {
00129          tagpos[n] = 0;
00130          taglen[n] = 0;
00131       }
00132 
00133       int lasttag = -1;
00134 
00135       for (UInt_t cur = 0; cur < lwords; ++cur) {
00136          uint64_t* ptag = (uint64_t*) pdata;
00137          bool find = false;
00138 
00139          for (int ntag=1;ntag<MAX__N_MOD;ntag++)
00140             if ((*ptag == vme_tags[ntag]) && (vme_tags[ntag]!=0)) {
00141                if (lasttag>=0) {
00142                   taglen[lasttag] = pdata - tagpos[lasttag];
00143                   lasttag = -1;
00144                }
00145 
00146                if (tagpos[ntag]==0) {
00147                   pdata+=2; cur+=1;
00148                   tagpos[ntag] = pdata;
00149                   lasttag = ntag;
00150                } else {
00151                   TGo4Log::Error("FORMAT ERROR found tag %lld twice\n", vme_tags[ntag]);
00152                   pdata+=2; cur+=1;
00153                }
00154 
00155                find = true;
00156                break;
00157             }
00158 
00159          if (!find) pdata++;
00160       }
00161 
00162       if (lasttag>=0)
00163          taglen[lasttag] = pdata - tagpos[lasttag];
00164 
00165       // for (int ntag=0;ntag<numtags;ntag++)
00166       //    if (tagpos[ntag])
00167       //       printf("TAG %d POS %lu LEN %d\n", ntag, tagpos[ntag] - p0, taglen[ntag]);
00168 
00169 
00170       // if (GetTriggerNumber()==8) {
00171       //   fOutputEvent->SetValid(kFALSE);
00172       //   return;
00173       // }
00174 
00175 
00176       // actually process data in subroutines:
00177 
00178       if (tagpos[VME__ID_1182] && taglen[VME__ID_1182])
00179          Process1182(0, tagpos[VME__ID_1182], taglen[VME__ID_1182]);  // 1182
00180       if (tagpos[VME__ID_1183] && taglen[VME__ID_1183])
00181          Process1182(1, tagpos[VME__ID_1183], taglen[VME__ID_1183]);  // 1183
00182 
00183       for (int tdc=VME__ID_TDC1;tdc<=VME__ID_TDC8;tdc++)
00184          if (tagpos[tdc] && taglen[tdc])
00185             Process1290(tdc-VME__ID_TDC1, tagpos[tdc], taglen[tdc]);  // all TDCs
00186 
00187       for (int qdc=VME__ID_QDC1;qdc<=VME__ID_QDC3;qdc++)
00188          if (tagpos[qdc] && taglen[qdc])
00189             Process965(qdc-VME__ID_QDC1, tagpos[qdc], taglen[qdc]);  // all QDCs
00190 
00191       for (int fpga=VME__ID_FPGA1;fpga<=VME__ID_FPGA4;fpga++)
00192          if (tagpos[fpga] && taglen[fpga])
00193             ProcessFPGA_TDC(fpga-VME__ID_FPGA1, (uint32_t*) tagpos[fpga], taglen[fpga]);  // all FPGAs
00194 
00195       if (tagpos[VME__ID_QFW] && taglen[VME__ID_QFW])
00196          ProcessQFW((uint32_t*)tagpos[VME__ID_QFW], taglen[VME__ID_QFW]);  // QFW
00197    }
00198 }
00199 
00200 
00201 
00202 
00203 void TMbsCrateProc::Process1182(int num, int* pdata, int len)
00204 {
00205    if (len < 2 + NUM_1182_CH ) {
00206       cout <<"TBeamMonitorProc:Process1182 data length"<< len << "not sufficient!" <<endl;
00207       return;
00208    }
00209 
00210    if (num>=MAX_1182) {
00211       cout << "Wrong ID=" << num << " of 1182 module" << endl;
00212       return;
00213    }
00214 
00215    // skip event header:
00216    int header = *pdata++;
00217    if (L1182_DEBUG)  printf("1182 header:0x%0x \n",header);
00218 
00219    // skip status
00220    int status = *pdata++;
00221    if (L1182_DEBUG)
00222       printf("1182 status:0x%0x :  \n"
00223             "        conversion complete    (bit0): 0x%x\n"
00224             "        conversion in progress (bit1): 0x%x\n"
00225             "        front(1)/rear(0) panel (bit2): 0x%x\n"
00226             "        Event buffer not full  (bit3): 0x%x\n"
00227             "        Event count       (bits 4..7): 0x%x\n"
00228             "        should be 0            (bit8): 0x%x\n"
00229             "        should be 0            (bit9): 0x%x\n",
00230             status, status & 1, (status >> 1) & 1 , (status >> 2) & 1, (status >> 3) & 1,
00231             (status >> 4) & 0xf,  (status >> 8) & 1, (status >> 9) & 1);
00232 
00233    for(int ch=0;ch<NUM_1182_CH;++ch) {
00234       int val = *pdata++;
00235       f1182h[num][ch]->Fill(val);
00236 
00237       fOutputEvent->fData1182[num][ch] = val; // output event to root tree
00238    }
00239 
00240    fOutputEvent->SetValid(kTRUE);
00241 }
00242 
00243 void TMbsCrateProc::Process1290(int num, int* pdata, unsigned int len)
00244 {
00245    if (num >= MAX_1290) {
00246       cout << "Wrong 1290 index " << num << endl;
00247       return;
00248    }
00249 
00250    int expected_geo = 0;
00251 
00252    if (num<0) {
00253       // if number is not specified, try to identify it base on GEO value
00254       expected_geo = T1290Data::FindGeo(pdata, len);
00255       if (expected_geo<=0) {
00256          printf("ERROR: Did not found GEO in the data\n");
00257          return;
00258       }
00259 
00260       switch (expected_geo) {
00261          case 5: num = 8; break;
00262          case 6: num = 9; break;
00263          case 7: num = 10; break;
00264          case 8: num = 11; break;
00265          case 9: num = 12; break;
00266          case 10: num = 13; break;
00267          case 11: num = 14; break;
00268          default:
00269             printf("Unsupported GEO code %d\n", expected_geo);
00270             return;
00271       }
00272 
00273       // printf("Found GEO code %d defined num %d\n", expected_geo, num);
00274 
00275    } else {
00276       switch(num) {
00277          case 0: expected_geo = 8; break;
00278          case 1: expected_geo = 9; break;
00279          case 2: expected_geo = 10; break;
00280          case 3: expected_geo = 11; break;
00281          case 4: expected_geo = 12; break;
00282          case 5: expected_geo = 13; break;
00283          case 6: expected_geo = 14; break;
00284          case 7: expected_geo = 15; break;
00285        }
00286    }
00287    // printf("Process1290 num = %d expected GEO = %d len = %u\n", num, expected_geo, len);
00288 
00289    fOutputEvent->fMtdc[num].Unpack(pdata, len, expected_geo);
00290 
00291    fTDC[num].FillHistos(fOutputEvent->fMtdc[num]);
00292 
00293    fOutputEvent->SetValid(kTRUE);
00294 }
00295 
00296 void TMbsCrateProc::Process965(int num, int* pdata, unsigned int len)
00297 {
00298         int geo, crate, count;
00299         Int_t timeOffset;
00300         int data;
00301         
00302         if (num >= MAX_965) {
00303                 cout << "Wrong 965 index " << num << endl;
00304                 return;
00305         }
00306         geo = 0;
00307         timeOffset = 0;
00308         data = *pdata++;
00309         len--;
00310         count = 0;
00311         if (num<0) {
00312                 // if number is not specified, try to identify it base on GEO value
00313                 geo = MQDC_t::FindGeo(pdata, &count, &crate);
00314                 if (geo<=0) {
00315                         printf("ERROR: Did not found GEO in the data\n");
00316                         return;
00317                 }
00318                 switch (geo) {
00319                         case 0: num = 0; break;
00320                         case 1: num = 1; break;
00321                         case 2: num = 2; break;
00322                         default:
00323                                 printf("Unsupported GEO code %d\n", geo);
00324                                 return;
00325                 }
00326         }
00327         else
00328         {
00329                 if(((data>>24) & 0x7) == 0x2)
00330                 {
00331                         count = (data >> 8) & 0x3f;
00332                 }
00333                 switch(num) {
00334                         case 0: geo = 0; break;
00335                         case 1: geo = 1; break;
00336                         case 2: geo = 2; break;
00337                 }
00338         }
00339         fOutputEvent->fMqdc[num].Unpack(pdata, count, geo);
00340         
00341         for (int ch=0; ch<MQDC_t::NumChan; ch++) {
00342                 if(fOutputEvent->fMqdc[num].charge[ch]>0)
00343                         fQdc_Charge[num][ch]->Fill(fOutputEvent->fMqdc[num].charge[ch]);
00344          }
00345         
00346         fOutputEvent->SetValid(kTRUE);
00347 }
00348 
00349 void TMbsCrateProc::ProcessFPGA_TDC(int num, uint32_t* pdata, unsigned int len)
00350 {
00351    if ((num<0) || (num>=MAX_FPGA_TDC)) {
00352       TGo4Log::Error("Error number %d for FPGA TDC", num);
00353       return;
00354    }
00355 
00356    uint32_t l_dat = *pdata++; // module header
00357    if ( (l_dat & 0xffff0000) != 0xabcd0000 ) {
00358       printf ("this is not a vulom header, exiting.. \n");
00359       return;
00360    }
00361 
00362    uint32_t l_nr_cha   = (l_dat & 0xff);
00363 
00364    if (l_nr_cha+2 != len) {
00365       printf ("wrong length in vulom header, exiting.. \n");
00366       return;
00367    }
00368 
00369    pdata++;  // vulom tdc fifo header
00370 
00371    while (l_nr_cha-- > 0) {
00372 
00373       uint32_t l_da0 = *pdata++;
00374       
00375 
00376       FPGA_TDC_hit hit;
00377 
00378       hit.ch_ix        = (l_da0 & 0x78000000) >> 27;  //  4 bit
00379       hit.coarse_ct    = (l_da0 & 0x3fff800)  >> 11;  // 15 bit
00380       hit.ch_tim       = (l_da0 & 0x7ff);             // 11 bit
00381 
00382       // old format
00383       // l_ch_ix        = (l_da0 & 0xfc000000) >> 26;
00384       // l_coarse_ct    = (l_da0 & 0x1fffc00)  >> 10;
00385       // l_ch_tim       = (l_da0 & 0x3ff);
00386 
00387       fOutputEvent->fFPGA[num].push_back(hit);
00388 
00389       if (hit.ch_ix<MAX_FPGA_TDC_Channel)
00390          fFPGA_Ch[num][hit.ch_ix]->Fill(hit.ch_tim);
00391          
00392          
00393     }
00394 
00395    fOutputEvent->SetValid(kTRUE);
00396 }
00397 
00398 void TMbsCrateProc::ProcessQFW(uint32_t* pdata, unsigned int len)
00399 {
00400    if (len!=9) {
00401       printf ("Wrong QFW format");
00402       return;
00403    }
00404 
00405 
00406    for (int n=0;n<4;n++) {
00407       fOutputEvent->fQFW.counters[n] = *pdata++;
00408       fQFWcnt->SetBinContent(n+1, fOutputEvent->fQFW.counters[n]);
00409    }
00410 
00411    TString txt = "#splitline";
00412 
00413    for (int n=0;n<4;n++) {
00414       fOutputEvent->fQFW.errcnt[n] = *pdata++;
00415       fQFWerr->SetBinContent(n+1, fOutputEvent->fQFW.errcnt[n]);
00416 
00417       txt+=Form("{#scale[2.0]{#color[2]{Ch%d cnt:%10u err:%10u}}}", n, fOutputEvent->fQFW.counters[n], fOutputEvent->fQFW.errcnt[n]);
00418    }
00419 
00420    fOutputEvent->fQFW.setup = *pdata;
00421 
00422    txt+=Form("{#scale[2.0]{#color[2]{Setup: %d}}}", fOutputEvent->fQFW.setup);
00423 
00424    fQFWInfo->SetText(0.2, 0.5, txt.Data());
00425 
00426    fOutputEvent->SetValid(kTRUE);
00427 }
00428 

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