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 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
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
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
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
00095
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
00112
00113
00114 if (subevt->GetProcid() == roc::proc_COSY_Nov11) {
00115
00116
00117
00118 fOutputEvent->SetValid(kTRUE);
00119
00120 Int_t *pdata = subevt->GetDataField();
00121 UInt_t lwords = subevt->GetIntLen();
00122
00123
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
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 if (tagpos[VME__ID_1182] && taglen[VME__ID_1182])
00179 Process1182(0, tagpos[VME__ID_1182], taglen[VME__ID_1182]);
00180 if (tagpos[VME__ID_1183] && taglen[VME__ID_1183])
00181 Process1182(1, tagpos[VME__ID_1183], taglen[VME__ID_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]);
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]);
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]);
00194
00195 if (tagpos[VME__ID_QFW] && taglen[VME__ID_QFW])
00196 ProcessQFW((uint32_t*)tagpos[VME__ID_QFW], taglen[VME__ID_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
00216 int header = *pdata++;
00217 if (L1182_DEBUG) printf("1182 header:0x%0x \n",header);
00218
00219
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;
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
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
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
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
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++;
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++;
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;
00379 hit.coarse_ct = (l_da0 & 0x3fff800) >> 11;
00380 hit.ch_tim = (l_da0 & 0x7ff);
00381
00382
00383
00384
00385
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