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