00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #include "RawData/RawDigitDataBlock.h"
00014
00015 enum EDebugDigitDataBlock {
00016 dbg_DumpHeaderOnUnpack = 0x0001,
00017 dbg_DumpCrateOnUnpack = 0x0002,
00018 dbg_DumpDigitOnUnpack = 0x0004,
00019 dbg_DumpOnlyHeader = 0x0008,
00020 dbg_DumpOnlyFirstLast = 0x0010
00021 };
00022
00023 UInt_t RawDigitDataBlock::fgDebugFlags = 0;
00024
00025
00026 #include "RawData/RawQieMCDigit.h"
00027 #include "RawData/RawVaMCDigit.h"
00028 #include "RawData/RawQieDigiDigit.h"
00029 #include "RawData/RawVaDigiDigit.h"
00030
00031 #include <set>
00032 #include <vector>
00033 #include <map>
00034 using namespace std;
00035 #include <cstring>
00036
00037 #include "MessageService/MsgStream.h"
00038 #include "MessageService/MsgService.h"
00039 CVSID("$Id: RawDigitDataBlock.cxx,v 1.35 2007/06/04 21:02:44 rhatcher Exp $");
00040
00041 #include "RawData/RawBlockRegistry.h"
00042 REGISTERRAWBLOCK(RawDigitDataBlock,kMdBlockCrateReadout,0);
00043
00044 ClassImp(RawDigitDataBlock)
00045
00046
00047 RawDigitDataBlock::RawDigitDataBlock() :
00048 fRawCrateStatuses(0), fRawDigits(0),
00049 fCrates(-1), fNPedMode(0), fNSparsMode(0), fNCommonMode(0),
00050 fSeenErrorsQIE(0), fSeenErrorsVA(0)
00051 {
00052
00053 }
00054
00055
00056 RawDigitDataBlock::RawDigitDataBlock(const Int_t *block)
00057 : RawDataBlock(block),
00058 fRawCrateStatuses(0), fRawDigits(0),
00059 fCrates(-1), fNPedMode(0), fNSparsMode(0), fNCommonMode(0),
00060 fSeenErrorsQIE(0), fSeenErrorsVA(0)
00061 {
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 }
00092
00093
00094 RawDigitDataBlock::~RawDigitDataBlock()
00095 {
00096 if (fRawDigits) {
00097 fRawDigits->Delete();
00098 delete fRawDigits;
00099 fRawDigits = 0;
00100 }
00101 if (fRawCrateStatuses) {
00102 fRawCrateStatuses->Delete();
00103 delete fRawCrateStatuses;
00104 fRawCrateStatuses = 0;
00105 }
00106 return;
00107 }
00108
00109
00110 RawDigitDataBlock& RawDigitDataBlock::operator=(const RawDigitDataBlock& rhs)
00111 {
00112
00113 if (this != &rhs) {
00114 RawDataBlock::operator=(rhs);
00115 if (fRawDigits) {
00116 fRawDigits->Delete();
00117 delete fRawDigits;
00118 fRawDigits = 0;
00119 }
00120 if (fRawCrateStatuses) {
00121 fRawCrateStatuses->Delete();
00122 delete fRawCrateStatuses;
00123 fRawCrateStatuses = 0;
00124 }
00125 fCrates = -1;
00126 fNPedMode = 0;
00127 fNSparsMode = 0;
00128 fNCommonMode = 0;
00129 fSeenErrorsQIE = 0;
00130 fSeenErrorsVA = 0;
00131 }
00132 return *this;
00133 }
00134
00135
00136 Int_t RawDigitDataBlock::GetNumberOfDigits() const
00137 {
00138
00139
00140
00141 if ( ! fRawDigits ) FillRawDigits();
00142 return fRawDigits->GetEntriesFast();
00143 }
00144
00145
00146 Short_t RawDigitDataBlock::GetNumberOfCrates() const
00147 {
00148
00149 if ( fCrates < 0 ) FillCrateModes();
00150 return fCrates;
00151 }
00152
00153
00154 Short_t RawDigitDataBlock::GetNPedModeCrates() const
00155 {
00156
00157 if ( fCrates < 0 ) FillCrateModes();
00158 return fNPedMode;
00159 }
00160
00161
00162 Short_t RawDigitDataBlock::GetNSparsModeCrates() const
00163 {
00164
00165 if ( fCrates < 0 ) FillCrateModes();
00166 return fNSparsMode;
00167 }
00168
00169
00170 Short_t RawDigitDataBlock::GetNCommonModeCrates() const
00171 {
00172
00173 if ( fCrates < 0 ) FillCrateModes();
00174 return fNCommonMode;
00175 }
00176
00177
00178 Int_t RawDigitDataBlock::GetNumOfErrorDigits() const
00179 {
00180
00181
00182
00183 if ( ! fRawDigits ) FillRawDigits();
00184
00185 Int_t nerrDigits = 0;
00186 TIter rditer = GetDatumIter();
00187 while ( RawDigit *rd = dynamic_cast<RawDigit*>(rditer()) ) {
00188 if (rd->GetErrorCode()) nerrDigits++;
00189 }
00190 return nerrDigits;
00191 }
00192
00193
00194 Char_t RawDigitDataBlock::GetSeenErrorMaskQIE() const
00195 {
00196
00197
00198
00199 if ( ! fRawDigits ) FillRawDigits();
00200 return fSeenErrorsQIE;
00201 }
00202
00203
00204 Char_t RawDigitDataBlock::GetSeenErrorMaskVA() const
00205 {
00206
00207
00208
00209 if ( ! fRawDigits ) FillRawDigits();
00210 return fSeenErrorsVA;
00211 }
00212
00213
00214 Int_t RawDigitDataBlock::IsOverlapTfBoundary() const
00215 {
00216
00217
00218
00219
00220
00221
00222 if ( ! fRawDigits ) FillRawDigits();
00223
00224 MSG("RawData",Msg::kDebug)
00225 << " NCrates " << GetNumberOfCrates() << endl;
00226
00227 Int_t overlapCode = 0;
00228
00229 map<VldTimeStamp,UInt_t> timestampCnt;
00230 map<Int_t,UInt_t> crateCnt;
00231
00232 TIter citr(fRawCrateStatuses);
00233 while ( RawDigitCrateStatus* cstat =
00234 dynamic_cast<RawDigitCrateStatus*>(citr()) ) {
00235 VldTimeStamp crateT0 = cstat->GetCrateT0();
00236 Int_t crateNum = cstat->GetCrate();
00237 timestampCnt[crateT0]++;
00238 crateCnt[crateNum]++;
00239 MSG("RawData",Msg::kDebug)
00240 << " crateNum " << crateNum << " to " << crateT0 << endl;
00241 }
00242
00243
00244 if ( timestampCnt.size() > 1 ) overlapCode += 1;
00245
00246
00247 map<Int_t,UInt_t>::const_iterator crateCntItr = crateCnt.begin();
00248 while ( crateCntItr != crateCnt.end() ) {
00249 if ( (*crateCntItr).second != 1 ) overlapCode += 2;
00250 crateCntItr++;
00251 }
00252
00253 MSG("RawData",Msg::kDebug)
00254 << " return code " << overlapCode << endl;
00255 return overlapCode;
00256 }
00257
00258
00259 const RawDigit* RawDigitDataBlock::At(Int_t idx) const
00260 {
00261
00262
00263
00264 if ( ! fRawDigits ) FillRawDigits();
00265 return (RawDigit*) fRawDigits->At(idx);
00266 }
00267
00268
00269 TIter RawDigitDataBlock::GetDatumIter(Bool_t dir) const
00270 {
00271
00272
00273
00274 if ( ! fRawDigits ) FillRawDigits();
00275 return TIter(fRawDigits,dir);
00276 }
00277
00278
00279 Int_t RawDigitDataBlock::IndexOf(RawDigit *rawdigit) const
00280 {
00281
00282
00283
00284 if ( ! fRawDigits ) FillRawDigits();
00285 return fRawDigits->IndexOf(rawdigit);
00286 }
00287
00288
00289 VldContext RawDigitDataBlock::GetVldContext() const
00290 {
00291
00292
00293
00294 if ( ! fRawDigits ) FillRawDigits();
00295
00296 VldTimeStamp vts(2038,1,18,0,0,0);
00297
00298 TIter citr(fRawCrateStatuses);
00299 while ( RawDigitCrateStatus* cstat =
00300 dynamic_cast<RawDigitCrateStatus*>(citr()) ) {
00301 VldTimeStamp t0 = cstat->GetCrateT0();
00302 if (t0<vts) vts = t0;
00303 }
00304
00305 RawBlockId rbid = GetBlockId();
00306 return VldContext(rbid.GetDetector(),rbid.GetSimFlag(),vts);
00307
00308 }
00309
00310
00311 void RawDigitDataBlock::FillRawDigits() const
00312 {
00313
00314
00315 if ( fRawDigits ) return;
00316 if ( fSize <= 0 || fRawBlock == 0) {
00317 MSG("RawData",Msg::kWarning)
00318 << "RawDigitDataBlock::FillRawDigits empty block? "
00319 << fSize << " " << fRawBlock << endl;
00320 return;
00321 }
00322
00323 fRawCrateStatuses = new TObjArray();
00324 fRawDigits = new TObjArray();
00325 RawDigitCrateStatus *cratestatus = 0;
00326 RawDigit *rawdigit = 0;
00327 const Int_t *p = fRawBlock;
00328 const Int_t *end = fRawBlock + fSize;
00329
00330 RawBlockId rbid = GetBlockId();
00331 p += 3;
00332
00333 if (fgDebugFlags&dbg_DumpHeaderOnUnpack) {
00334 MSG("RawData",Msg::kInfo)
00335 << "RawDigitDataBlock::FillRawDigits "
00336 << " fSize " << fSize
00337 << " id " << rbid.AsString()
00338 << endl;
00339 }
00340
00341 while (p<end) {
00342
00343 cratestatus = new RawDigitCrateStatus(rbid,p);
00344 fRawCrateStatuses->Add(cratestatus);
00345 Int_t npairs = cratestatus->GetEntries();
00346
00347 if (fgDebugFlags&dbg_DumpCrateOnUnpack) cratestatus->Print();
00348
00349 for (Int_t ipair = 0; ipair < npairs; ipair++) {
00350
00351
00352 ElecType::Elec_t etype = cratestatus->GetElecType();
00353
00354
00355
00356 switch (rbid.GetSimFlag()) {
00357 case SimFlag::kData:
00358 case SimFlag::kDaqFakeData:
00359 switch (etype) {
00360 case ElecType::kVA:
00361 rawdigit = new RawVaDigit(p,cratestatus);
00362 break;
00363 case ElecType::kQIE:
00364 rawdigit = new RawQieDigit(p,cratestatus);
00365 break;
00366 default:
00367 rawdigit = new RawDigit(p,cratestatus);
00368 break;
00369 }
00370 break;
00371 case SimFlag::kMC:
00372 switch (etype) {
00373 case ElecType::kVA:
00374 rawdigit = new RawVaDigiDigit(p,cratestatus);
00375 break;
00376 case ElecType::kQIE:
00377 rawdigit = new RawQieDigiDigit(p,cratestatus);
00378 break;
00379 default:
00380 MSG("RawData",Msg::kError)
00381 << "RawDigitDataBlock::FillRawDigits SimFlag "
00382 << SimFlag::AsString(rbid.GetSimFlag())
00383 << " ElecType " << ElecType::AsString(etype)
00384 << endl << " attempt to move past problem " << endl;
00385 p += 3;
00386 break;
00387 };
00388 break;
00389 case SimFlag::kReroot:
00390 switch (etype) {
00391 case ElecType::kVA:
00392 rawdigit = new RawVaMCDigit(p,cratestatus);
00393 break;
00394 case ElecType::kQIE:
00395 rawdigit = new RawQieMCDigit(p,cratestatus);
00396 break;
00397 case ElecType::kReroot:
00398 {
00399 if (rbid.GetDetector() == Detector::kNear) {
00400 static int nmsg = 10;
00401 if (nmsg) {
00402 MSG("RawData",Msg::kWarning)
00403 << "RawDigitDataBlock::FillRawDigits SimFlag "
00404 << SimFlag::AsString(rbid.GetSimFlag())
00405 << " ElecType " << ElecType::AsString(etype)
00406 << " in Detector "
00407 << Detector::AsString(rbid.GetDetector())
00408 << endl
00409 << " treat as kQIE for RawQieMCDigit creation"
00410 << endl;
00411 if (nmsg) {
00412 if (--nmsg == 0)
00413 MSG("RawData",Msg::kWarning)
00414 << " ... last warning of this type" << endl;
00415 }
00416 }
00417 rawdigit = new RawQieMCDigit(p,cratestatus);
00418 break;
00419 }
00420 else
00421 MSG("RawData",Msg::kError)
00422 << "RawDigitDataBlock::FillRawDigits SimFlag "
00423 << SimFlag::AsString(rbid.GetSimFlag())
00424 << " ElecType " << ElecType::AsString(etype)
00425 << endl << " attempt to move past problem " << endl;
00426 p += 3;
00427 break;
00428 }
00429 default:
00430 MSG("RawData",Msg::kError)
00431 << "RawDigitDataBlock::FillRawDigits SimFlag "
00432 << SimFlag::AsString(rbid.GetSimFlag())
00433 << " ElecType " << ElecType::AsString(etype)
00434 << endl << " attempt to move past problem " << endl;
00435 p += 3;
00436 break;
00437 }
00438 break;
00439 case SimFlag::kUnknown:
00440 MSG("RawData",Msg::kError)
00441 << "RawDigitDataBlock::FillRawDigits SimFlag "
00442 << SimFlag::AsString(rbid.GetSimFlag())
00443 << endl << " attempt to move past problem " << endl;
00444 p += 2;
00445 break;
00446 }
00447
00448 fRawDigits->Add(rawdigit);
00449
00450 if (fgDebugFlags&dbg_DumpDigitOnUnpack) rawdigit->Print();
00451 if (p>end) {
00452 MSG("RawData",Msg::kWarning)
00453 << "RawDigitDataBlock::FillRawDigits crate info seems trashed"
00454 << endl << " SimFlag " << SimFlag::AsString(rbid.GetSimFlag())
00455 << " ElecType " << ElecType::AsString(etype)
00456 << endl;
00457 break;
00458 }
00459 }
00460 }
00461
00462
00463
00464
00465
00466 PostFillRawDigits();
00467 }
00468
00469
00470 void RawDigitDataBlock::PostFillRawDigits() const
00471 {
00472
00473
00474
00475
00476
00477 UInt_t ncaperr=0, ncapmenuerr=0, ncapsharederr=0;
00478 UInt_t ntranserr=0, ntranssharederr=0;
00479
00480
00481
00482
00483 set<RawChannelId> rcidCapIdErrors;
00484 set<RawChannelId> rcidTransferErrors;
00485 vector<RawQieDigit*> otherQieDigitsCapId;
00486 vector<RawQieDigit*> otherQieDigitsTrans;
00487 otherQieDigitsCapId.reserve(fRawDigits->GetLast()+1);
00488 otherQieDigitsTrans.reserve(fRawDigits->GetLast()+1);
00489
00490 TIter rditr(fRawDigits);
00491 while ( RawDigit* rd = dynamic_cast<RawDigit*>(rditr()) ) {
00492 RawChannelId rcid = rd->GetChannel();
00493 Char_t err = rd->GetErrorCode();
00494
00495 ElecType::Elec_t etype = rcid.GetElecType();
00496
00497 if ( etype == ElecType::kVA ) fSeenErrorsVA |= err;
00498 else if ( etype == ElecType::kQIE ) fSeenErrorsQIE |= err;
00499
00500
00501 if ( etype != ElecType::kQIE ) continue;
00502 RawQieDigit* rdqie = dynamic_cast<RawQieDigit*>(rd);
00503 if ( !rdqie ) continue;
00504
00505 if ( err & RawQieDigit::kCapIdError ) {
00506
00507 ncaperr++;
00508 MSG("Raw",Msg::kVerbose)
00509 << "raw CapIdError on rcid " << rcid.AsString("c") << endl;
00510 rcid.ClearModeBits();
00511 rcidCapIdErrors.insert(rcid);
00512 }
00513 else otherQieDigitsCapId.push_back(rdqie);
00514
00515 if ( err & (RawQieDigit::kParityError|RawQieDigit::kMisCountError) ) {
00516
00517 ntranserr++;
00518 MSG("Raw",Msg::kVerbose)
00519 << "raw " << RawQieDigit::AsString((RawQieDigit::EQieErrorCode)err)
00520 << " (" << (int)err << ") on rcid " << rcid.AsString("c") << endl;
00521 rcid.ClearModeBits();
00522 rcidTransferErrors.insert(rcid);
00523 }
00524 else otherQieDigitsTrans.push_back(rdqie);
00525
00526 }
00527
00528
00529 set<RawChannelId>::const_iterator rcidItr;
00530
00531
00532 rcidItr = rcidCapIdErrors.begin();
00533 while ( rcidItr != rcidCapIdErrors.end() ) {
00534 RawChannelId rcidBadMenu = *rcidItr++;
00535 for (size_t iqied=0; iqied < otherQieDigitsCapId.size(); ++iqied) {
00536 RawQieDigit* rdqie = otherQieDigitsCapId[iqied];
00537 RawChannelId rcid = rdqie->GetChannel();
00538 rcid.ClearModeBits();
00539 if ( rcid == rcidBadMenu ) {
00540 rdqie->SetCapIdSameMenuError();
00541 ncapmenuerr++;
00542 fSeenErrorsQIE |= RawQieDigit::kCapIdSameMenuError;
00543 }
00544 else if ( rcid.IsSameMinder(rcidBadMenu) ) {
00545 rdqie->SetCapIdSharedMinderError();
00546 ncapsharederr++;
00547 fSeenErrorsQIE |= RawQieDigit::kCapIdSharedMinderError;
00548 }
00549 }
00550 }
00551
00552
00553 rcidItr = rcidTransferErrors.begin();
00554 while ( rcidItr != rcidTransferErrors.end() ) {
00555 RawChannelId rcidBadMenu = *rcidItr++;
00556 for (size_t iqied=0; iqied < otherQieDigitsTrans.size(); ++iqied) {
00557 RawQieDigit* rdqie = otherQieDigitsTrans[iqied];
00558 RawChannelId rcid = rdqie->GetChannel();
00559 if ( rcid.IsSameMinder(rcidBadMenu) ) {
00560 rdqie->SetTransferSharedMinderError();
00561 ntranssharederr++;
00562 fSeenErrorsQIE |= RawQieDigit::kTransferSharedMinderError;
00563 }
00564 }
00565 }
00566
00567 if ( ncaperr > 0 ) {
00568 MAXMSG("Raw",Msg::kInfo,10)
00569 << "CapId Error on " << ncaperr <<" digits, "
00570 << ncapmenuerr << "," << ncapsharederr
00571 << " other digits shared same menus,minders."
00572 << endl;
00573 }
00574 if ( ntranserr > 0 ) {
00575 MAXMSG("Raw",Msg::kInfo,10)
00576 << "Transfer Error on " << ntranserr <<" digits, "
00577 << ntranssharederr
00578 << " other digits shared same minders."
00579 << endl;
00580 }
00581 }
00582
00583
00584 void RawDigitDataBlock::FillCrateModes() const
00585 {
00586
00587
00588
00589 if ( ! fRawDigits ) FillRawDigits();
00590
00591 fCrates = fNPedMode = fNSparsMode = fNCommonMode = 0;
00592
00593 TIter citr(fRawCrateStatuses);
00594
00595 TObject *tobj;
00596 RawDigitCrateStatus *cstat;
00597
00598 while ( ( tobj = citr.Next() ) ) {
00599 cstat = dynamic_cast<RawDigitCrateStatus*>(tobj);
00600 if (cstat) {
00601 ++fCrates;
00602 if (cstat->GetPedMode()) ++fNPedMode;
00603 if (cstat->GetSparsMode()) ++fNSparsMode;
00604 if (cstat->GetCommonMode()) ++fNCommonMode;
00605 }
00606 }
00607
00608 }
00609
00610
00611 std::ostream& RawDigitDataBlock::FormatToOStream(ostream& os,
00612 Option_t *option) const
00613 {
00614
00615 RawDataBlock::FormatToOStream(os,option);
00616 if (strchr(option,'X')!=0) return os;
00617
00618
00619
00620 os << " NumDigits=" << GetNumberOfDigits()
00621 << " (w/Errors=" << GetNumOfErrorDigits() << ")"
00622 << " NumCrates=" << GetNumberOfCrates()
00623 << " (PedSub=" << GetNPedModeCrates()
00624 << ",Spars=" << GetNSparsModeCrates()
00625 << ",CommonMode=" << GetNCommonModeCrates()
00626 << ")"
00627 << endl;
00628
00629 os << " SeenErrorMask "
00630 << "QIE 0x" << hex << setfill('0') << setw(2)
00631 << (int)GetSeenErrorMaskQIE() << setfill(' ') << dec << " "
00632 << "VA 0x" << hex << setfill('0') << setw(2)
00633 << (int)GetSeenErrorMaskVA() << setfill(' ') << dec << ","
00634 << " OverlapTfBoundary: "
00635 << ((IsOverlapTfBoundary())?"Yes":"No")
00636 << endl;
00637
00638 if (strchr(option,'-')!=0) return os;
00639 if (fgDebugFlags&dbg_DumpOnlyHeader) return os;
00640
00641 const RawDigitCrateStatus *lastcrate = 0;
00642
00643 RawDigit *rd, *rdprev = 0;
00644 TIter rditer = GetDatumIter();
00645 Int_t tmin=0x7fffffff, tmax=-1;
00646 while ( ( rd = dynamic_cast<RawDigit*>(rditer()) ) ) {
00647 if (rd->GetCrateStatus() != lastcrate) {
00648 if ((fgDebugFlags&dbg_DumpOnlyFirstLast) && rdprev )
00649 os << " " << (*rdprev) << endl;
00650 lastcrate = rd->GetCrateStatus();
00651 os << " " << (*lastcrate) << endl;
00652 if (fgDebugFlags&dbg_DumpOnlyFirstLast)
00653 os << " " << (*rd) << endl << " ..." << endl;
00654 }
00655 if (!fgDebugFlags&dbg_DumpOnlyFirstLast)
00656 os << " " << (*rd) << endl;
00657 rdprev = rd;
00658 Int_t tdc = rd->GetTDC();
00659 if (tdc<tmin) tmin = tdc;
00660 if (tdc>tmax) tmax = tdc;
00661 }
00662 if (fgDebugFlags&dbg_DumpOnlyFirstLast) {
00663 os << " " << (*rdprev) << endl;
00664 os << " TDC range all crates [" << tmin << ":" << tmax << "]" << endl;
00665 }
00666 os << endl;
00667 return os;
00668 }
00669
00670
00671