Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:35

0001 #include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
0002 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
0003 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
0004 #include <cstdio>
0005 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
0006 
0007 DCCFEBlock::DCCFEBlock(
0008     DCCDataUnpacker* u, EcalElectronicsMapper* m, DCCEventBlock* e, bool unpack, bool forceToKeepFRdata)
0009     : DCCDataBlockPrototype(u, m, e, unpack), checkFeId_(false), forceToKeepFRdata_(forceToKeepFRdata) {
0010   expXtalTSamples_ = mapper_->numbXtalTSamples();
0011   numbDWInXtalBlock_ = (expXtalTSamples_ - 2) / 4 + 1;
0012   unfilteredDataBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
0013   xtalGains_ = new short[expXtalTSamples_];
0014 }
0015 
0016 void DCCFEBlock::updateCollectors() {
0017   invalidBlockLengths_ = unpacker_->invalidBlockLengthsCollection();
0018   invalidTTIds_ = unpacker_->invalidTTIdsCollection();
0019   invalidZSXtalIds_ = unpacker_->invalidZSXtalIdsCollection();
0020 }
0021 
0022 int DCCFEBlock::unpack(const uint64_t** data, unsigned int* dwToEnd, bool zs, unsigned int expectedTowerID) {
0023   zs_ = zs;
0024   datap_ = data;
0025   data_ = *data;
0026   dwToEnd_ = dwToEnd;
0027 
0028   const unsigned int activeDCC = mapper_->getActiveSM();
0029 
0030   if ((*dwToEnd_) < 1) {
0031     if (!DCCDataUnpacker::silentMode_) {
0032       edm::LogWarning("IncorrectEvent") << "\n Unable to unpack Tower block for event " << event_->l1A() << " in fed "
0033                                         << activeDCC << "\n The end of event was reached "
0034                                         << "\n(or, previously, pointers intended to navigate outside of FedBlock "
0035                                            "(based on block sizes), and were stopped by setting dwToEnd_ to zero)";
0036       //TODO : add this to a dcc event size collection error?
0037     }
0038     return STOP_EVENT_UNPACKING;
0039   }
0040 
0041   lastStripId_ = 0;
0042   lastXtalId_ = 0;
0043   expTowerID_ = expectedTowerID;
0044 
0045   //Point to begin of block
0046   data_++;
0047 
0048   towerId_ = (*data_) & TOWER_ID_MASK;
0049   nTSamples_ = (*data_ >> TOWER_NSAMP_B) & TOWER_NSAMP_MASK;
0050   bx_ = (*data_ >> TOWER_BX_B) & TOWER_BX_MASK;
0051   l1_ = (*data_ >> TOWER_L1_B) & TOWER_L1_MASK;
0052   blockLength_ = (*data_ >> TOWER_LENGTH_B) & TOWER_LENGTH_MASK;
0053 
0054   event_->setFESyncNumbers(l1_, bx_, (short)(expTowerID_ - 1));
0055 
0056   //debugging
0057   //display(cout);
0058 
0059   ////////////////////////////////////////////////////
0060   // check that expected fe_id==fe_expected is on
0061   if (checkFeId_ && expTowerID_ != towerId_ &&
0062       expTowerID_ <= mapper_->getNumChannelsInDcc(activeDCC)) {  // fe_id must be within range foreseen in the FED
0063     if (!DCCDataUnpacker::silentMode_) {
0064       edm::LogWarning("IncorrectBlock") << "Expected tower ID is " << expTowerID_ << " while " << towerId_
0065                                         << " was found"
0066                                         << " (L1A " << event_->l1A() << " fed " << mapper_->getActiveDCC() << ")\n"
0067                                         << "  => Skipping to next FE block...";
0068     }
0069 
0070     fillEcalElectronicsError(invalidTTIds_);
0071 
0072     updateEventPointers();
0073     return SKIP_BLOCK_UNPACKING;
0074   }
0075 
0076   //////////////////////////////////////////////////////////
0077   // check that expected fe_id==fe_expected is off
0078   else if ((!checkFeId_) && towerId_ > mapper_->getNumChannelsInDcc(
0079                                            activeDCC)) {  // fe_id must still be within range foreseen in the FED
0080     if (!DCCDataUnpacker::silentMode_) {
0081       edm::LogWarning("IncorrectBlock") << "For event " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
0082                                         << " (there's no check fe_id==dcc_channel)"
0083                                         << "\n the FE_id found: " << towerId_
0084                                         << " exceeds max number of FE foreseen in fed"
0085                                         << "\n => Skipping to next FE block...";
0086     }
0087 
0088     updateEventPointers();
0089     return SKIP_BLOCK_UNPACKING;
0090   }
0091 
0092   // Check synchronization
0093   if (sync_) {
0094     const unsigned int dccBx = (event_->bx()) & TCC_BX_MASK;
0095     const unsigned int dccL1 = (event_->l1A()) & TCC_L1_MASK;
0096     const unsigned int fov = (event_->fov()) & H_FOV_MASK;
0097 
0098     if (!isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
0099       if (!DCCDataUnpacker::silentMode_) {
0100         // TODO: add check for status from Channel Status DB
0101 
0102         edm::LogWarning("IncorrectBlock")
0103             << "Synchronization error for Tower Block"
0104             << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower "
0105             << towerId_ << ")\n"
0106             << "  dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
0107             << "  => Skipping to next tower block";
0108       }
0109 
0110       //Note : add to error collection ?
0111       updateEventPointers();
0112       return SKIP_BLOCK_UNPACKING;
0113     }
0114   }
0115 
0116   // check number of samples
0117   if (nTSamples_ != expXtalTSamples_) {
0118     if (!DCCDataUnpacker::silentMode_) {
0119       edm::LogWarning("IncorrectBlock") << "Unable to unpack Tower Block " << towerId_ << " for event L1A "
0120                                         << event_->l1A() << " in fed " << mapper_->getActiveDCC()
0121                                         << "\n Number of time samples " << nTSamples_
0122                                         << " is not the same as expected (" << expXtalTSamples_ << ")"
0123                                         << "\n => Skipping to next tower block...";
0124     }
0125     //Note : add to error collection ?
0126     updateEventPointers();
0127     return SKIP_BLOCK_UNPACKING;
0128   }
0129 
0130   xtalBlockSize_ = numbDWInXtalBlock_ * 8;
0131   blockSize_ = blockLength_ * 8;
0132 
0133   if ((*dwToEnd_) < blockLength_) {
0134     if (!DCCDataUnpacker::silentMode_) {
0135       edm::LogWarning("IncorrectEvent") << "\n Unable to unpack Tower Block " << towerId_ << " for event L1A "
0136                                         << event_->l1A() << " in fed " << mapper_->getActiveDCC() << "\n Only "
0137                                         << ((*dwToEnd_) * 8) << " bytes are available while " << blockSize_
0138                                         << " are needed!"
0139                                         << "\n => Skipping to next fed block...";
0140     }
0141     //TODO : add to error collections
0142     return STOP_EVENT_UNPACKING;
0143   }
0144 
0145   if (!zs_ && !forceToKeepFRdata_) {
0146     if (unfilteredDataBlockLength_ != blockLength_) {
0147       if (!DCCDataUnpacker::silentMode_) {
0148         edm::LogWarning("IncorrectEvent")
0149             << "\n For event L1A " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower " << towerId_
0150             << "\n Expected block size is " << (unfilteredDataBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
0151             << " was found"
0152             << "\n => Skipping to next fed block...";
0153       }
0154 
0155       fillEcalElectronicsError(invalidBlockLengths_);
0156 
0157       //Safer approach...  - why pointers do not navigate in this case?
0158       return STOP_EVENT_UNPACKING;
0159     }
0160 
0161   } else if (!zs && forceToKeepFRdata_) {
0162     if (unfilteredDataBlockLength_ != blockLength_) {
0163       if (!DCCDataUnpacker::silentMode_) {
0164         edm::LogWarning("IncorrectBlock")
0165             << "For event L1A " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower " << towerId_
0166             << "\n Expected block size is " << (unfilteredDataBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
0167             << " was found"
0168             << "\n => Keeps unpacking as the unpacker was forced to keep FR data (by configuration) ...";
0169       }
0170 
0171       fillEcalElectronicsError(invalidBlockLengths_);
0172     }
0173 
0174   } else if (blockLength_ > unfilteredDataBlockLength_ || (blockLength_ - 1) < numbDWInXtalBlock_) {
0175     if (!DCCDataUnpacker::silentMode_) {
0176       edm::LogWarning("IncorrectEvent") << "\n For event L1A " << event_->l1A() << " and fed "
0177                                         << mapper_->getActiveDCC() << "\n The tower " << towerId_
0178                                         << " has a wrong number of bytes : " << (blockLength_ * 8)
0179                                         << "\n => Skipping to next fed block...";
0180     }
0181 
0182     fillEcalElectronicsError(invalidBlockLengths_);
0183 
0184     //Safer approach... - why pointers do not navigate in this case?
0185     return STOP_EVENT_UNPACKING;
0186   }
0187 
0188   // If the HLT says to skip this tower we skip it...
0189   if (!event_->getHLTChannel(towerId_)) {
0190     updateEventPointers();
0191     return SKIP_BLOCK_UNPACKING;
0192   }
0193   /////////////////////////////////////////////////
0194 
0195   unsigned int numbOfXtalBlocks = (blockLength_ - 1) / numbDWInXtalBlock_;
0196 
0197   // get XTAL Data
0198   unsigned int expStripID(0), expXtalID(0);
0199   //point to xtal data
0200   data_++;
0201 
0202   int statusUnpackXtal = 0;
0203 
0204   for (unsigned int numbXtal = 1; numbXtal <= numbOfXtalBlocks && statusUnpackXtal != SKIP_BLOCK_UNPACKING;
0205        numbXtal++) {
0206     if (!zs_ && !forceToKeepFRdata_) {
0207       expStripID = (numbXtal - 1) / 5 + 1;
0208       expXtalID = numbXtal - (expStripID - 1) * 5;
0209     }
0210 
0211     statusUnpackXtal = unpackXtalData(expStripID, expXtalID);
0212     if (statusUnpackXtal == SKIP_BLOCK_UNPACKING) {
0213       if (!DCCDataUnpacker::silentMode_) {
0214         edm::LogWarning("IncorrectBlock") << "For event L1A " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
0215                                           << "\n The tower " << towerId_ << " won't be unpacked further";
0216       }
0217     }
0218 
0219   }  // end loop over xtals of given FE
0220 
0221   updateEventPointers();
0222   return BLOCK_UNPACKED;
0223 }
0224 
0225 void DCCFEBlock::display(std::ostream& o) {
0226   o << "\n Unpacked Info for DCC Tower Block"
0227     << "\n DW1 ============================="
0228     << "\n Tower Id " << towerId_ << "\n Numb Samp " << nTSamples_ << "\n Bx " << bx_ << "\n L1 " << l1_
0229     << "\n blockLength " << blockLength_;
0230 }