00001
00002
00003
00004
00005
00006
00008
00009 #include "RerootExodus/RerootToRawDataModule.h"
00010 #include "RerootExodus/RerootExodus.h"
00011
00012 #include "MinosObjectMap/MomNavigator.h"
00013
00014 #include "MessageService/MsgService.h"
00015 #include "JobControl/JobCModuleRegistry.h"
00016 #include "JobControl/JobCommand.h"
00017
00018 #include "MINF_Classes/MINFast.h"
00019 #include "REROOT_Classes/REROOT_GeomMisc.h"
00020 #include "REROOT_Classes/REROOT_PlanePos.h"
00021 #include "REROOT_Classes/REROOT_PlaneSpec.h"
00022 #include "REROOT_Classes/REROOT_CellPos.h"
00023
00024 #include "Plex/PlexHandle.h"
00025
00026 #include "RawData/RawRecord.h"
00027 #include "RawData/RawDaqSnarlHeader.h"
00028 #include "RawData/RawDigitDataBlock.h"
00029 #include "RawData/RawBlockRegistry.h"
00030 #include "RawData/RawBlockId.h"
00031 #include "RawData/RawDigit.h"
00032 #include "RawData/RawMCDigitMixIn.h"
00033
00034 #include "TMath.h"
00035
00036 const UInt_t dbg_DumpAddToCrate = 0x0001;
00037 const UInt_t dbg_DumpNewCrate = 0x0002;
00038 const UInt_t dbg_PrintRawDigitDataBlock = 0x0004;
00039 const UInt_t dbg_WarnAllMissingRCId = 0x0008;
00040
00041 ClassImp(RerootToRawDataModule)
00042
00043
00044
00045
00046 CVSID("$Id: RerootToRawDataModule.cxx,v 1.49 2005/08/26 19:07:29 rhatcher Exp $");
00047 JOBMODULE(RerootToRawDataModule, "RerootToRawDataModule",
00048 "Builds RawRecord with RawDigitDataBlock");
00049
00050
00051
00052
00053 RerootToRawDataModule::RerootToRawDataModule()
00054 : random(0), fDebugFlags(0), fRawPeCut(0.2999),
00055 ncrates(0), workingcrates(0), cratesizeused(0),
00056 workingarray(0), display(0),
00057 Nplaneshit(0), ofMplanes(0)
00058 {
00059
00060
00061
00062
00063 random = new TRandom();
00064
00065
00066 detector = Detector::kUnknown;
00067
00068 ncrates = 128;
00069 cratesizeused = new TArrayI(ncrates);
00070 workingcrates = new TArrayI [ncrates];
00071
00072 Int_t init_alloc = 5 + 100*3;
00073 for (Int_t i=0; i<ncrates; i++) {
00074 cratesizeused->AddAt(0,i);
00075 workingcrates[i].Set(init_alloc);
00076 }
00077
00078 nwordsblock = 0;
00079 workingarray = new TArrayI(2);
00080
00081
00082 }
00083
00084
00085
00086 RerootToRawDataModule::~RerootToRawDataModule()
00087 {
00088 MSG("Exodus", Msg::kVerbose) << "RerootToRawDataModule::Destructor\n";
00089
00090 if (random) delete random;
00091 random = 0;
00092
00093 if (ncrates) {
00094 delete [] workingcrates;
00095 workingcrates = 0;
00096
00097 delete cratesizeused;
00098 cratesizeused = 0;
00099
00100 ncrates = 0;
00101 }
00102
00103 if (workingarray) delete workingarray;
00104 workingarray = 0;
00105
00106 if (display) delete display;
00107 display = 0;
00108
00109 }
00110
00111
00112
00113 JobCResult RerootToRawDataModule::Get(MomNavigator *mom)
00114 {
00115
00116
00117
00118 if (!gMINFast) {
00119 static int nmsg = 10;
00120 if (nmsg) {
00121 MSG("Exodus",Msg::kFatal)
00122 << "RerootToRawDataModule lacked gMINFast" << endl
00123 << " perhaps the input isn't a REROOT file"
00124 << endl;
00125 nmsg--;
00126 if (!nmsg) MSG("Exodus",Msg::kFatal)
00127 << " ... last such message" << endl;
00128 }
00129 return JobCResult::kError;
00130 }
00131
00132
00133
00134 InitWorkingArray();
00135
00136 ndigitsPerPlane.Reset();
00137
00138
00139 VldContext vldc = RerootExodus::BuildVldContext();
00140
00141
00142 PlexHandle ph(vldc);
00143
00144
00145 const TClonesArray *flsdigits = RerootExodus::GetFLSDigitList();
00146 REROOT_FLSDigit *flsdigit = 0;
00147 TIter diter(flsdigits);
00148
00149 PlexStripEndId seid;
00150 RawChannelId rcid;
00151 Float_t raw, tdc;
00152 Int_t isAB;
00153
00154
00155 Float_t tearly = 2e9;
00156
00157
00158
00159 Float_t ADAMO_RNULL = 699050. * (Float_t) (16<<26);
00160
00161
00162 while ( ( flsdigit = (REROOT_FLSDigit*) diter.Next() ) ) {
00163
00164 static int nmsgIsNull = 20;
00165
00166
00167 raw = flsdigit->RawA();
00168 tdc = flsdigit->TDCA();
00169 isAB = 0;
00170 if ( raw > 0.0 && raw < ADAMO_RNULL ) {
00171 seid = RerootExodus::PECAB2SEId(flsdigit->IPln(),flsdigit->IExtr(),
00172 flsdigit->ICell(),isAB);
00173
00174 rcid = ph.GetRawChannelId(seid);
00175 if (rcid.IsNull()) {
00176 if (( fDebugFlags & dbg_WarnAllMissingRCId) || nmsgIsNull>0)
00177 MSG("Exodus",Msg::kWarning)
00178 << "rcid.IsNull() on A side " << seid.AsString() << endl;
00179 if (nmsgIsNull==1 & !(fDebugFlags&dbg_WarnAllMissingRCId))
00180 MSG("Exodus",Msg::kWarning)
00181 << " ... last IsNull message" << endl;
00182 nmsgIsNull--;
00183 }
00184
00185 AddToCrate(seid,rcid,raw,tdc);
00186 if(tdc < tearly) tearly = tdc;
00187 }
00188
00189
00190 raw = flsdigit->RawB();
00191 tdc = flsdigit->TDCB();
00192 isAB = 1;
00193 if ( raw > 0.0 && raw < ADAMO_RNULL ) {
00194 seid = RerootExodus::PECAB2SEId(flsdigit->IPln(),flsdigit->IExtr(),
00195 flsdigit->ICell(),isAB);
00196
00197 rcid = ph.GetRawChannelId(seid);
00198 if (rcid.IsNull()) {
00199 if (( fDebugFlags & dbg_WarnAllMissingRCId) || nmsgIsNull>0)
00200 MSG("Exodus",Msg::kWarning)
00201 << "rcid.IsNull() on B side " << seid.AsString() << endl;
00202 if (nmsgIsNull==1 & !(fDebugFlags&dbg_WarnAllMissingRCId))
00203 MSG("Exodus",Msg::kWarning)
00204 << " ... last IsNull message" << endl;
00205 nmsgIsNull--;
00206 }
00207
00208 AddToCrate(seid,rcid,raw,tdc);
00209 if(tdc < tearly) tearly = tdc;
00210 }
00211 }
00212
00213
00214 RawDataBlock *rawblk = FinalizeWorkingArray();
00215 RawDigitDataBlock *rrdb = dynamic_cast<RawDigitDataBlock*>(rawblk);
00216
00217 if (fDebugFlags & dbg_PrintRawDigitDataBlock) rawblk->Print();
00218
00219
00220
00221
00222 Int_t run = RerootExodus::GetRunNo();
00223 Int_t snarl = RerootExodus::GetEventNo();
00224 Int_t trigbits = random->Integer(0x0fffffff);
00225 Short_t subrun = 0;
00226 Short_t runtype = 0;
00227 Int_t errcode = 0;
00228 static Int_t tf = 0;
00229 Int_t nrawdigits = (rrdb) ? rrdb->GetNumberOfDigits() : -1;
00230 Int_t spilltype = -1;
00231
00232
00233 VldTimeStamp trigTime(vldc.GetTimeStamp().GetSec(),
00234 (int)(tearly));
00235
00236 VldContext trigContext(vldc.GetDetector(),
00237 vldc.GetSimFlag(),
00238 trigTime);
00239
00240 RawDaqSnarlHeader *head =
00241 new RawDaqSnarlHeader(trigContext,run,subrun,runtype,++tf,
00242 snarl,trigbits,errcode,nrawdigits,spilltype);
00243
00244
00245
00246 RawRecord *rawrec = new RawRecord(head);
00247
00248
00249
00250 rawrec->AdoptRawBlock(rawblk);
00251
00252
00253
00254 rawrec->GetTempTags().Set("stream","DaqSnarl");
00255
00256
00257
00258 mom->AdoptFragment(rawrec);
00259
00260
00261
00262 return ApplyTrigger();
00263 }
00264
00265
00266
00267 JobCResult RerootToRawDataModule::ApplyTrigger()
00268 {
00269
00270
00271
00272
00273 if (Detector::kNear == detector) return JobCResult::kPassed;
00274
00275
00276 if (Nplaneshit<=0) return JobCResult::kPassed;
00277
00278
00279 Int_t first = 0;
00280 Int_t last = ndigitsPerPlane.GetSize()-1;
00281 for ( ; last>first; last-- ) if (ndigitsPerPlane[last]>0) break;
00282 for ( ; first<last; first++) if (ndigitsPerPlane[first]>0) break;
00283
00284
00285 if (last-first+1<Nplaneshit) return JobCResult::kFailed;
00286
00287 Int_t running_total = 0;
00288 Int_t excluded_plns = 0;
00289 for (Int_t plane = first; plane<=last; plane++) {
00290
00291
00292 PlexPlaneId pid(detector,plane);
00293 if (pid.GetPlaneCoverage() == PlaneCoverage::kNoActive) {
00294 excluded_plns++;
00295 if (ndigitsPerPlane[plane]>0)
00296 MSG("Exodus",Msg::kWarning)
00297 << "saw " << ndigitsPerPlane[plane]
00298 << " digits in uninstrumented plane "
00299 << pid << endl;
00300 else
00301 ndigitsPerPlane[plane] = -1;
00302 }
00303
00304
00305 if (ndigitsPerPlane[plane]>0) running_total++;
00306
00307
00308 Int_t window = ofMplanes + excluded_plns;
00309 if (plane>=window-1 && plane-window>=0) {
00310 Int_t ngoingout = ndigitsPerPlane[plane-window];
00311 if (ngoingout < 0) excluded_plns--;
00312 else if (ngoingout > 0) running_total--;
00313 }
00314
00315
00316 if ( running_total >= Nplaneshit ) return JobCResult::kPassed;
00317
00318 }
00319
00320 return JobCResult::kFailed;
00321 }
00322
00323
00324
00325 JobCResult RerootToRawDataModule::Reco(MomNavigator *mom)
00326 {
00327
00328
00329
00330
00331
00332
00333
00334 TObject *obj;
00335
00336
00337 RawRecord *rawrec = dynamic_cast<RawRecord *>
00338 (mom->GetFragment("RawRecord"));
00339 if ( ! rawrec ) {
00340 MSG("Exodus",Msg::kFatal) << "RerootToRawDataModule::Reco" <<
00341 " failed to fin a \"RawRecord\"" << endl;
00342 return JobCResult::kError;
00343 }
00344
00345
00346 VldContext vldc = rawrec->GetRawHeader()->GetVldContext();
00347
00348
00349 PlexHandle ph(vldc);
00350
00351
00352 if ( ! display ) display =
00353 new CheezyDisplay("RerootToRawDataModule",
00354 "RerootToRawDataModule display");
00355 display->ClearLists();
00356 display->SetVldContext(vldc);
00357
00358
00359
00360 RawDigitDataBlock *digitblk = 0;
00361 TIter blkiter = rawrec->GetRawBlockIter();
00362 while ( ( obj = blkiter.Next() ) ) {
00363 digitblk = dynamic_cast<RawDigitDataBlock*>(obj);
00364 if (digitblk) {
00365
00366
00367 RawDigit *digit = 0;
00368 TIter diter = digitblk->GetDatumIter();
00369
00370 while ( ( digit = (RawDigit*) diter.Next() ) ) {
00371
00372
00373
00374
00375 RawMCDigitMixIn *truthDigit = dynamic_cast<RawMCDigitMixIn*>(digit);
00376 if (truthDigit) {
00377 PlexStripEndId seid(truthDigit->GetTrueSEIdEncoded());
00378 display->AddStripEndId(seid,kTRUE);
00379 }
00380
00381
00382 RawChannelId rcid = digit->GetChannel();
00383 PlexSEIdAltL altlist = ph.GetSEIdAltL(rcid);
00384 altlist.SetFirst();
00385 while ( altlist.IsValid() ) {
00386 PlexStripEndId seid = altlist.GetCurrentSEId();
00387 display->AddStripEndId(seid,kFALSE);
00388 altlist.Next();
00389 }
00390 }
00391
00392 }
00393 }
00394
00395
00396 display->Draw();
00397
00398 return JobCResult::kAOK;
00399
00400 }
00401
00402
00403
00404 void RerootToRawDataModule::InitWorkingArray(void)
00405 {
00406
00407
00408
00409 for (Int_t i=0; i<ncrates; i++) {
00410 cratesizeused->AddAt(0,i);
00411 }
00412 nwordsblock = 0;
00413
00414 detector = RerootExodus::GetDetector();
00415 }
00416
00417
00418
00419 void RerootToRawDataModule::AddToCrate(const PlexStripEndId& seid,
00420 const RawChannelId& rcid,
00421 Float_t raw, Float_t tdc)
00422 {
00423
00424
00425
00426 if (raw < fRawPeCut ) {
00427 static Float_t last_cut_msg = -1;
00428 if (last_cut_msg != fRawPeCut) {
00429
00430 last_cut_msg = fRawPeCut;
00431 MSG("Exodus",Msg::kInfo)
00432 << "::AddToCrate cutting all raw values < "
00433 << fRawPeCut << endl;
00434 }
00435 return;
00436 }
00437
00438
00439 Int_t plane = seid.GetPlane();
00440 if (ndigitsPerPlane.GetSize()<plane+1) ndigitsPerPlane.Set(plane+1);
00441 ndigitsPerPlane[plane]++;
00442
00443 Int_t crate = rcid.GetCrate();
00444 if (crate>=ncrates) {
00445 MSG("Exodus",Msg::kFatal)
00446 << "RerootToRawDataModule::AddToCrate "
00447 << crate << " larger than allocated " << ncrates << endl;
00448 return;
00449 }
00450
00451 TArrayI *wcrate = &workingcrates[crate];
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 const Int_t hsize = 4;
00467 const Int_t ndigits_indx = 1;
00468 const Int_t nw_digit = 3;
00469
00470
00471 Int_t used = cratesizeused->At(crate);
00472 Int_t need = used + nw_digit;
00473 if (0 == used) need += hsize;
00474
00475 const Int_t slop = 100;
00476
00477 if (wcrate->GetSize() < need) {
00478 wcrate->Set(need+slop);
00479 }
00480
00481
00482 if (0 == used) {
00483
00484 const Int_t modes = 0x07;
00485 Int_t etype = rcid.GetElecType();
00486 Int_t packedCrate = (modes << 8) |
00487 (etype << 6) | (crate & 0x0000003f);
00488 wcrate->AddAt(packedCrate,used++);
00489
00490 if (used != ndigits_indx) {
00491
00492 MSG("Exodus",Msg::kFatal)
00493 << "RerootToRawDataModule::AddToCrate ndigits_indx "
00494 << ndigits_indx << " != " << used << endl;
00495 }
00496 wcrate->AddAt(0,used++);
00497
00498 VldTimeStamp vts = RerootExodus::BuildVldContext().GetTimeStamp();
00499 wcrate->AddAt(vts.GetSec(),used++);
00500
00501
00502
00503 wcrate->AddAt(0,used++);
00504
00505
00506 if (fDebugFlags & dbg_DumpNewCrate) {
00507 printf("new header for crate %3d %#8.8x\n",crate,packedCrate);
00508 }
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 const int signbit = 0x80000000;
00518
00519
00520
00521 const int chaddmask = 0x1fff;
00522 const int chaddshift = 16;
00523 const int adcmask = 0x00003fff;
00524 const int tdcmask = 0x3fffffff;
00525
00526
00527
00528
00529
00530
00531 Int_t chadd = rcid.GetChAdd();
00532 if (chadd > chaddmask) {
00533
00534 static int nmsg_chadd = 5;
00535 if (nmsg_chadd) {
00536 MSG("Exodus",Msg::kFatal)
00537 << "RerootToRawDataModule::AddToCrate chadd "
00538 << hex << chadd << dec << " truncated from "
00539 << hex << rcid.GetChAdd() << dec << endl;
00540 nmsg_chadd--;
00541 if (nmsg_chadd==0)
00542 MSG("Exodus",Msg::kFatal)
00543 << " ... last of these messages" << endl;
00544 }
00545 }
00546 chadd &= chaddmask;
00547
00548 Int_t iadc = TMath::Nint( raw * 60.0 );
00549 if(rcid.GetElecType()==ElecType::kQIE) iadc+=50;
00550 if (iadc > adcmask ) {
00551
00552 static int nmsg_adc = 5;
00553 if (nmsg_adc) {
00554 MSG("Exodus",Msg::kWarning)
00555 << "RerootToRawDataModule::AddToCrate iadc "
00556 << iadc << " does not fit in field (max "
00557 << adcmask << ")" << endl;
00558 nmsg_adc--;
00559 if (nmsg_adc==0)
00560 MSG("Exodus",Msg::kWarning)
00561 << " ... last of these messages" << endl;
00562 }
00563 iadc = TMath::Max(0,TMath::Min(iadc,adcmask));
00564 }
00565 iadc &= adcmask;
00566
00567
00568 Float_t tdc_convert = 0.1;
00569 switch (rcid.GetElecType()) {
00570 case (ElecType::kVA):
00571
00572 tdc_convert = 1.5625;
00573 break;
00574 case (ElecType::kQIE):
00575
00576 tdc_convert = 1000./53.1;
00577
00578 if (rcid.GetDetector() == Detector::kCalDet)
00579 tdc_convert = 1.5625*16.0*58.0/77.0;
00580 break;
00581 default:
00582 break;
00583 }
00584 Int_t itdc = TMath::Nint( tdc / tdc_convert );
00585
00586 if (itdc > tdcmask ) {
00587
00588 static int nmsg_tdc = 5;
00589 if (nmsg_tdc) {
00590 MSG("Exodus",Msg::kWarning)
00591 << "RerootToRawDataModule::AddToCrate itdc "
00592 << itdc << " does not fit in field (max "
00593 << tdcmask << ")" << endl;
00594 nmsg_tdc--;
00595 if (nmsg_tdc==0)
00596 MSG("Exodus",Msg::kWarning)
00597 << " ... last of these messages" << endl;
00598 }
00599 itdc = TMath::Max(0,TMath::Min(itdc,tdcmask));
00600 }
00601 itdc &= tdcmask;
00602
00603
00604 if (fDebugFlags & dbg_DumpAddToCrate) {
00605 MSG("Exodus",Msg::kInfo)
00606 << "AddToCrate " << rcid.AsString()
00607 << " seid " << seid.AsString("c")
00608 << " raw " << raw << " time " << tdc
00609 << endl
00610 << hex << setfill('0')
00611 << " stored as adc 0x" << setw(8) << iadc
00612 << " tdc 0x" << setw(8) << itdc
00613 << setfill(' ') << dec
00614 << endl;
00615 }
00616
00617
00618
00619 Int_t upper = signbit | (chadd<<chaddshift) | iadc;
00620 Int_t lower = itdc;
00621 Int_t extra = seid.GetEncoded();
00622
00623
00624 wcrate->AddAt(upper,used++);
00625 wcrate->AddAt(lower,used++);
00626 wcrate->AddAt(extra,used++);
00627
00628
00629 Int_t npairs = (used-hsize)/nw_digit;
00630 wcrate->AddAt(npairs,ndigits_indx);
00631
00632
00633 cratesizeused->AddAt(used,crate);
00634
00635 }
00636
00637
00638
00639 RawDataBlock* RerootToRawDataModule::FinalizeWorkingArray(void)
00640 {
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 Int_t need = 3;
00669 for (Int_t crate=0; crate < ncrates; crate++) {
00670 need += cratesizeused->At(crate);
00671 }
00672
00673
00674 if (workingarray->GetSize() < need) {
00675 workingarray->Set(0);
00676 workingarray->Set(need);
00677 }
00678
00679 RawBlockRegistry& rbr = RawBlockRegistry::Instance();
00680 RawBlockProxy* rbp = rbr.LookUp("RawDigitDataBlock");
00681
00682 Bool_t isDCS = rbp->IsDCS();
00683 Int_t majorId = rbp->GetMajorId();
00684
00685 RawBlockProxy* rbp2 = rbr.LookUp(isDCS,majorId);
00686 if ( rbp2 != rbp ) cout << "RawBlockProxy cross check failed" << endl;
00687
00688 Int_t minorId = 0;
00689 RawBlockId rbid(majorId,minorId,isDCS,detector,SimFlag::kReroot);
00690 MSG("Exodus", Msg::kDebug)
00691 << " to be stored with RawBlockId "
00692 << " 0x" << hex << rbid.GetEncoded() << dec
00693 << " == " << rbid.AsString() << endl
00694 << " majorId " << majorId << " minorId " << minorId
00695 << ((isDCS) ? " DCS " : " DAQ ")
00696 << " " << Detector::AsString(detector) << endl;
00697
00698 Int_t checksum = 0xdeadbeef;
00699
00700 Int_t& indx = nwordsblock;
00701 indx = 0;
00702 workingarray->AddAt(need,indx++);
00703 workingarray->AddAt(checksum,indx++);
00704 workingarray->AddAt(rbid.GetEncoded(),indx++);
00705 for (Int_t crate=0; crate<ncrates; crate++) {
00706 Int_t csize = cratesizeused->At(crate);
00707 TArrayI *wcrate = &workingcrates[crate];
00708 Int_t *array = wcrate->GetArray();
00709 for (Int_t i=0; i<csize; i++) {
00710 workingarray->AddAt(array[i],indx++);
00711 }
00712 }
00713
00714
00715 int xsum_version = 0;
00716 rdxsum_fill((long*)workingarray->GetArray(),xsum_version);
00717
00718
00719 return rbp->CreateRawDataBlock(workingarray->GetArray());
00720
00721 }
00722
00723
00724
00725 void RerootToRawDataModule::HandleCommand(JobCommand *command)
00726 {
00727
00728
00729
00730 TString cmd = command->PopCmd();
00731 if (cmd == "Set") {
00732 TString opt = command->PopOpt();
00733 if (opt == "fRawPeCut") fRawPeCut = command->PopFloatOpt();
00734 else if (opt == "RawPeCut") fRawPeCut = command->PopFloatOpt();
00735 else if (opt == "fDebugFlags") fDebugFlags = command->PopIntOpt();
00736 else if (opt == "Trigger") {
00737 Nplaneshit = command->PopIntOpt();
00738 ofMplanes = command->PopIntOpt();
00739 MSG("Exodus", Msg::kInfo)
00740 << "RerootToRawDataModule: Trigger is "
00741 << Nplaneshit << " of " << ofMplanes << endl;
00742 }
00743 else {
00744 MSG("Exodus", Msg::kWarning)
00745 << "RerootToRawDataModule: Unrecognized option " << opt << endl;
00746 }
00747 } else {
00748 MSG("Exodus", Msg::kWarning)
00749 << "RerootToRawDataModule: Unrecognized command " << cmd << endl;
00750 }
00751 }
00752
00753