Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
0002 #include "EventFilter/EcalRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h"
0003 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
0004 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.h"
0005 
0006 #include "EventFilter/EcalRawToDigi/interface/DCCEEEventBlock.h"
0007 #include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
0008 #include "EventFilter/EcalRawToDigi/interface/DCCSCBlock.h"
0009 #include "EventFilter/EcalRawToDigi/interface/DCCEETCCBlock.h"
0010 #include "EventFilter/EcalRawToDigi/interface/DCCEESRPBlock.h"
0011 #include <sys/time.h>
0012 
0013 #include <iomanip>
0014 #include <sstream>
0015 
0016 DCCEEEventBlock::DCCEEEventBlock(DCCDataUnpacker* u,
0017                                  EcalElectronicsMapper* m,
0018                                  bool hU,
0019                                  bool srpU,
0020                                  bool tccU,
0021                                  bool feU,
0022                                  bool memU,
0023                                  bool forceToKeepFRdata)
0024     : DCCEventBlock(u, m, hU, srpU, tccU, feU, memU, forceToKeepFRdata) {
0025   //Builds a tower unpacker block
0026   towerBlock_ = new DCCSCBlock(u, m, this, feUnpacking_, forceToKeepFRdata_);
0027 
0028   //Builds a srp unpacker block
0029   srpBlock_ = new DCCEESRPBlock(u, m, this, srpUnpacking_);
0030 
0031   //Builds a tcc unpacker block
0032   tccBlock_ = new DCCEETCCBlock(u, m, this, tccUnpacking_);
0033 }
0034 
0035 void DCCEEEventBlock::unpack(const uint64_t* buffer, size_t numbBytes, unsigned int expFedId) {
0036   reset();
0037 
0038   eventSize_ = numbBytes;
0039   data_ = buffer;
0040 
0041   // First Header Word of fed block
0042   fedId_ = ((*data_) >> H_FEDID_B) & H_FEDID_MASK;
0043   bx_ = ((*data_) >> H_BX_B) & H_BX_MASK;
0044   l1_ = ((*data_) >> H_L1_B) & H_L1_MASK;
0045   triggerType_ = ((*data_) >> H_TTYPE_B) & H_TTYPE_MASK;
0046 
0047   // Check if fed id is the same as expected...
0048   if (fedId_ != expFedId) {
0049     if (!DCCDataUnpacker::silentMode_) {
0050       edm::LogWarning("IncorrectEvent") << "\n For event L1A: " << l1_ << "\n Expected FED id is: " << expFedId
0051                                         << " while current FED id is: " << fedId_
0052                                         << "\n => Skipping to next fed block...";
0053     }
0054 
0055     //TODO : add this to an error event collection
0056 
0057     return;
0058   }
0059 
0060   // Check if this event is an empty event
0061   if (eventSize_ == EMPTYEVENTSIZE) {
0062     if (!DCCDataUnpacker::silentMode_) {
0063       edm::LogWarning("IncorrectEvent") << "\n Event L1A: " << l1_ << " is empty for fed: " << fedId_
0064                                         << "\n => Skipping to next fed block...";
0065     }
0066     return;
0067 
0068   }
0069 
0070   //Check if event size allows at least building the header
0071   else if (eventSize_ < HEADERSIZE) {
0072     if (!DCCDataUnpacker::silentMode_) {
0073       edm::LogError("IncorrectEvent") << "\n Event L1A: " << l1_ << " in fed: " << fedId_ << "\n Event size is "
0074                                       << eventSize_ << " bytes while the minimum is " << HEADERSIZE << " bytes"
0075                                       << "\n => Skipping to next fed block...";
0076     }
0077 
0078     //TODO : add this to a dcc size error collection
0079 
0080     return;
0081   }
0082 
0083   //Second Header Word of fed block
0084   data_++;
0085 
0086   blockLength_ = (*data_) & H_EVLENGTH_MASK;
0087   dccErrors_ = ((*data_) >> H_ERRORS_B) & H_ERRORS_MASK;
0088   runNumber_ = ((*data_) >> H_RNUMB_B) & H_RNUMB_MASK;
0089 
0090   if (eventSize_ != blockLength_ * 8) {
0091     if (!DCCDataUnpacker::silentMode_) {
0092       edm::LogError("IncorrectEvent") << "\n Event L1A: " << l1_ << " in fed: " << fedId_ << "\n size is " << eventSize_
0093                                       << " bytes while " << (blockLength_ * 8) << " are set in the event header "
0094                                       << "\n => Skipping to next fed block...";
0095       //TODO : add this to a dcc size error collection
0096     }
0097     return;
0098   }
0099 
0100   //Third Header Word  of fed block
0101   data_++;
0102 
0103   // bits 0.. 31 of the 3rd DCC header word
0104   runType_ = (*data_) & H_RTYPE_MASK;
0105 
0106   fov_ = ((*data_) >> H_FOV_B) & H_FOV_MASK;
0107 
0108   // bits 32.. 47 of the 3rd DCC header word
0109   detailedTriggerType_ = ((*data_) >> H_DET_TTYPE_B) & H_DET_TTYPE_MASK;
0110 
0111   //Forth Header Word
0112   data_++;
0113   orbitCounter_ = ((*data_) >> H_ORBITCOUNTER_B) & H_ORBITCOUNTER_MASK;
0114   sr_ = ((*data_) >> H_SR_B) & B_MASK;
0115   zs_ = ((*data_) >> H_ZS_B) & B_MASK;
0116   tzs_ = ((*data_) >> H_TZS_B) & B_MASK;
0117 
0118   // MEM (forces readout of MEM channels if enabled)is only used in the EE DCCs and for FOV >1
0119   mem_ = ((*data_) >> H_MEM_B) & B_MASK;
0120   if (fov_ < 2) {
0121     mem_ = 0;
0122   }
0123 
0124   bool ignoreSR(true);
0125 
0126   srChStatus_ = ((*data_) >> H_SRCHSTATUS_B) & H_CHSTATUS_MASK;
0127 
0128   // getting TCC channel status bits
0129   tccChStatus_[0] = ((*data_) >> H_TCC1CHSTATUS_B) & H_CHSTATUS_MASK;
0130   tccChStatus_[1] = ((*data_) >> H_TCC2CHSTATUS_B) & H_CHSTATUS_MASK;
0131   tccChStatus_[2] = ((*data_) >> H_TCC3CHSTATUS_B) & H_CHSTATUS_MASK;
0132   tccChStatus_[3] = ((*data_) >> H_TCC4CHSTATUS_B) & H_CHSTATUS_MASK;
0133 
0134   // FE  channel Status data
0135   int channel(0);
0136   for (int dw = 0; dw < 5; dw++) {
0137     data_++;
0138     for (int i = 0; i < 14; i++, channel++) {
0139       unsigned int shift = i * 4;  //each channel has 4 bits
0140       feChStatus_[channel] = ((*data_) >> shift) & H_CHSTATUS_MASK;
0141     }
0142   }
0143 
0144   // debugging
0145   //display(cout);
0146 
0147   // pointer for the
0148   std::vector<short>::iterator it;
0149 
0150   // Update number of available dwords
0151   dwToEnd_ = blockLength_ - HEADERLENGTH;
0152 
0153   int STATUS = unpackTCCBlocks();
0154 
0155   if (STATUS != STOP_EVENT_UNPACKING && (feUnpacking_ || srpUnpacking_)) {
0156     //NMGA note : SR comes before TCC blocks
0157     // Emmanuelle please change this in the digi to raw
0158 
0159     // Unpack SRP block
0160     if (srChStatus_ != CH_TIMEOUT && srChStatus_ != CH_DISABLED) {
0161       STATUS = srpBlock_->unpack(&data_, &dwToEnd_, SRP_NUMBFLAGS);
0162       if (STATUS == BLOCK_UNPACKED) {
0163         ignoreSR = false;
0164       }
0165     }
0166   }
0167 
0168   // See number of FE channels that we need according to the trigger type //
0169   // TODO : WHEN IN LOCAL MODE WE SHOULD CHECK RUN TYPE
0170   unsigned int numbChannels(0);
0171 
0172   if (triggerType_ == PHYSICTRIGGER) {
0173     numbChannels = 68;
0174   } else if (triggerType_ == CALIBRATIONTRIGGER) {
0175     numbChannels = 70;
0176   } else {
0177     if (!DCCDataUnpacker::silentMode_) {
0178       edm::LogError("IncorrectEvent") << "\n Event L1A: " << l1_ << " in fed: " << fedId_
0179                                       << "\n Event has an unsupported trigger type " << triggerType_
0180                                       << "\n => Skipping to next fed block...";
0181       //TODO : add this to a dcc trigger type error collection
0182     }
0183     return;
0184   }
0185 
0186   // note: there is no a-priori check that number_active_channels_from_header
0187   //          equals number_channels_found_in_data.
0188   //          The checks are doing f.e. by f.e. only.
0189 
0190   if (feUnpacking_ || memUnpacking_) {
0191     it = feChStatus_.begin();
0192 
0193     // fields for tower recovery code
0194     unsigned int next_tower_id = 1000;
0195     const uint64_t* next_data = data_;
0196     unsigned int next_dwToEnd = dwToEnd_;
0197 
0198     // looping over FE channels, i.e. tower blocks
0199     for (unsigned int chNumber = 1; chNumber <= numbChannels && STATUS != STOP_EVENT_UNPACKING; chNumber++, it++) {
0200       //for( unsigned int i=1; chNumber<= numbChannels; chNumber++, it++ ){
0201 
0202       const short chStatus(*it);
0203 
0204       // skip unpacking if channel disabled
0205       if (chStatus == CH_DISABLED) {
0206         continue;
0207       }
0208 
0209       // force MEM readout if mem_ is enabled in EEs regardless on ch suppress status flag
0210       if (chStatus == CH_SUPPRESS && !mem_) {
0211         continue;
0212       }
0213 
0214       // issuiung messages for problematic cases, even though handled by the DCC
0215       // and skip channel
0216       if (chStatus == CH_TIMEOUT || chStatus == CH_HEADERERR || chStatus == CH_LINKERR || chStatus == CH_LENGTHERR ||
0217           chStatus == CH_IFIFOFULL || chStatus == CH_L1AIFIFOFULL) {
0218         if (!DCCDataUnpacker::silentMode_) {
0219           const int val = unpacker_->getCCUValue(fedId_, chNumber);
0220           const bool ttProblem = (val == 13) || (val == 14);
0221           if (!ttProblem) {
0222             edm::LogWarning("IncorrectBlock")
0223                 << "Bad channel status: " << chStatus << " in the DCC channel: " << chNumber << " (LV1 " << l1_
0224                 << " fed " << fedId_ << ")\n"
0225                 << "  => DCC channel is not being unpacked";
0226           }
0227         }
0228         continue;
0229       }
0230 
0231       // preserve data pointer
0232       const uint64_t* const prev_data = data_;
0233       const unsigned int prev_dwToEnd = dwToEnd_;
0234 
0235       // skip corrupted/problematic data block
0236       if (chNumber >= next_tower_id) {
0237         data_ = next_data;
0238         dwToEnd_ = next_dwToEnd;
0239         next_tower_id = 1000;
0240       }
0241 
0242       // Unpack Tower (Xtal Block)
0243       if (feUnpacking_ && chNumber <= 68) {
0244         //  in case of SR (data are 0 suppressed)
0245         if (sr_) {
0246           const bool applyZS = (fov_ == 0) ||  // backward compatibility with FOV = 0;
0247                                ignoreSR || (chStatus == CH_FORCEDZS1) ||
0248                                ((srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) != SRP_FULLREADOUT);
0249 
0250           STATUS = towerBlock_->unpack(&data_, &dwToEnd_, applyZS, chNumber);
0251 
0252           // If there is a decision to fully suppress data this is updated in channel status by the dcc
0253           //if ( ( srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) != SRP_NREAD ){
0254           //    STATUS = towerBlock_->unpack(&data_,&dwToEnd_,applyZS,chNumber);
0255           //}
0256         }
0257         // no SR (possibly 0 suppression flags)
0258         else {
0259           // if tzs_ data are not really suppressed, even though zs flags are calculated
0260           if (tzs_) {
0261             zs_ = false;
0262           }
0263           STATUS = towerBlock_->unpack(&data_, &dwToEnd_, zs_, chNumber);
0264         }
0265       }
0266 
0267       // Unpack Mem blocks
0268       if (memUnpacking_ && chNumber > 68) {
0269         STATUS = memBlock_->unpack(&data_, &dwToEnd_, chNumber);
0270       }
0271 
0272       // corruption recovery
0273       if (STATUS == SKIP_BLOCK_UNPACKING) {
0274         data_ = prev_data;
0275         dwToEnd_ = prev_dwToEnd;
0276 
0277         next_tower_id = next_tower_search(chNumber);
0278 
0279         next_data = data_;
0280         next_dwToEnd = dwToEnd_;
0281 
0282         data_ = prev_data;
0283         dwToEnd_ = prev_dwToEnd;
0284       }
0285     }
0286     // closing loop over FE/TTblock channels
0287 
0288   }  // check if we need to perform unpacking of FE or mem data
0289 
0290   if (headerUnpacking_)
0291     addHeaderToCollection();
0292 }
0293 
0294 int DCCEEEventBlock::unpackTCCBlocks() {
0295   int STATUS(BLOCK_UNPACKED);
0296   std::vector<short>::iterator it;
0297   unsigned int tccChId(0);
0298   for (it = tccChStatus_.begin(); it != tccChStatus_.end(); it++, tccChId++) {
0299     if ((*it) != CH_TIMEOUT && (*it) != CH_DISABLED) {
0300       STATUS = tccBlock_->unpack(&data_, &dwToEnd_, tccChId);
0301       if (STATUS == STOP_EVENT_UNPACKING)
0302         break;
0303     }
0304   }
0305   return STATUS;
0306 }