Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
0002 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
0003 #include "EventFilter/EcalRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h"
0004 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
0005 #include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
0006 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.h"
0007 #include "EventFilter/EcalRawToDigi/interface/DCCTCCBlock.h"
0008 #include "EventFilter/EcalRawToDigi/interface/DCCSRPBlock.h"
0009 #include <sys/time.h>
0010 
0011 #include <iomanip>
0012 #include <sstream>
0013 
0014 DCCEventBlock::DCCEventBlock(DCCDataUnpacker* u,
0015                              EcalElectronicsMapper* m,
0016                              bool hU,
0017                              bool srpU,
0018                              bool tccU,
0019                              bool feU,
0020                              bool memU,
0021                              bool forceToKeepFRdata)
0022     : unpacker_(u),
0023       mapper_(m),
0024       headerUnpacking_(hU),
0025       srpUnpacking_(srpU),
0026       tccUnpacking_(tccU),
0027       feUnpacking_(feU),
0028       memUnpacking_(memU),
0029       forceToKeepFRdata_(forceToKeepFRdata) {
0030   // Build a Mem Unpacker Block
0031   memBlock_ = new DCCMemBlock(u, m, this);
0032 
0033   // setup and initialize ch status vectors
0034   for (int feChannel = 1; feChannel <= 70; feChannel++) {
0035     feChStatus_.push_back(0);
0036     hlt_.push_back(1);
0037   }
0038   for (int tccChannel = 1; tccChannel <= 4; tccChannel++) {
0039     tccChStatus_.push_back(0);
0040   }
0041 
0042   // setup and initialize sync vectors
0043   for (int feChannel = 1; feChannel <= 70; feChannel++) {
0044     feBx_.push_back(-1);
0045     feLv1_.push_back(-1);
0046   }
0047   for (int tccChannel = 1; tccChannel <= 4; tccChannel++) {
0048     tccBx_.push_back(-1);
0049     tccLv1_.push_back(-1);
0050   }
0051   srpBx_ = -1;
0052   srpLv1_ = -1;
0053 }
0054 
0055 void DCCEventBlock::reset() {
0056   // reset sync vectors
0057   for (int feChannel = 1; feChannel <= 70; feChannel++) {
0058     feBx_[feChannel - 1] = -1;
0059     feLv1_[feChannel - 1] = -1;
0060   }
0061   for (int tccChannel = 1; tccChannel <= 4; tccChannel++) {
0062     tccBx_[tccChannel - 1] = -1;
0063     tccLv1_[tccChannel - 1] = -1;
0064   }
0065   srpBx_ = -1;
0066   srpLv1_ = -1;
0067 }
0068 
0069 void DCCEventBlock::enableSyncChecks() {
0070   towerBlock_->enableSyncChecks();
0071   tccBlock_->enableSyncChecks();
0072   memBlock_->enableSyncChecks();
0073   srpBlock_->enableSyncChecks();
0074 }
0075 
0076 void DCCEventBlock::enableFeIdChecks() { towerBlock_->enableFeIdChecks(); }
0077 
0078 unsigned int DCCEventBlock::next_tower_search(const unsigned int current_tower_id) {
0079   const uint64_t* const prev_data = data_;
0080   const unsigned int prev_dwToEnd = dwToEnd_;
0081 
0082   // expected LV1, BX, #TS
0083   const uint32_t lv1 = ((l1_ - 1) & 0xFFF);
0084   const uint32_t bx = (bx_ != 3564) ? bx_ : 0;
0085   const uint32_t ts = mapper_->numbXtalTSamples();
0086 
0087   // construct tower header and mask
0088   const uint64_t s_hi = 0xC0000000 + lv1;
0089   const uint64_t s_lo = 0xC0000000 + (bx << 16) + (ts << 8);
0090 
0091   const uint64_t sign = (s_hi << 32) + s_lo;
0092   const uint64_t mask = 0xC0001FFFDFFF7F00;
0093 
0094   // step forward to skip header word of problematic tower
0095   data_++;
0096   dwToEnd_--;
0097 
0098   //std::cerr << "header of bad tower = " << current_tower_id << " #" << dwToEnd_ << " 0x" << std::hex << *data_ << std::dec << std::endl;
0099   //std::cerr << "mask and sign = 0x" << std::hex << mask << " 0x" << sign << std::dec << std::endl;
0100 
0101   // navigate through tower data blocks to find tower block header
0102   while (dwToEnd_ > 0) {
0103     data_++;
0104     dwToEnd_--;
0105 
0106     //std::cerr << current_tower_id << " #" << dwToEnd_ << " 0x" << std::hex << *data_ << " 0x" << (*data_ & mask) << std::dec << std::endl;
0107 
0108     if ((*data_ & mask) == sign) {
0109       const unsigned int next_tower_id = (*data_) & 0xFF;
0110 
0111       if (next_tower_id <= current_tower_id)
0112         continue;
0113 
0114       //std::cerr << "next tower = " << next_tower_id << std::endl;
0115 
0116       // step back one word of the next tower header
0117       data_--;
0118       dwToEnd_++;
0119 
0120       return next_tower_id;
0121     }
0122   }
0123 
0124   // can't find next tower header
0125   // restore data pointer
0126   data_ = prev_data;
0127   dwToEnd_ = prev_dwToEnd;
0128   return 1000;
0129 }
0130 
0131 void DCCEventBlock::updateCollectors() {
0132   dccHeaders_ = unpacker_->dccHeadersCollection();
0133 
0134   memBlock_->updateCollectors();
0135   tccBlock_->updateCollectors();
0136   srpBlock_->updateCollectors();
0137   towerBlock_->updateCollectors();
0138 }
0139 
0140 void DCCEventBlock::addHeaderToCollection() {
0141   EcalDCCHeaderBlock theDCCheader;
0142 
0143   // container for fed_id (601-654 for ECAL)
0144   theDCCheader.setFedId(fedId_);
0145 
0146   // this needs to be migrated to the ECAL mapping package
0147 
0148   // dccId is number internal to ECAL running 1.. 54.
0149   // convention is that dccId = (fed_id - 600)
0150   int dccId = mapper_->getActiveSM();
0151   // DCCHeaders follow  the same convenction
0152   theDCCheader.setId(dccId);
0153 
0154   theDCCheader.setRunNumber(runNumber_);
0155   theDCCheader.setBasicTriggerType(triggerType_);
0156   theDCCheader.setLV1(l1_);
0157   theDCCheader.setBX(bx_);
0158   theDCCheader.setOrbit(orbitCounter_);
0159   theDCCheader.setErrors(dccErrors_);
0160   theDCCheader.setSelectiveReadout(sr_);
0161   theDCCheader.setZeroSuppression(zs_);
0162   theDCCheader.setTestZeroSuppression(tzs_);
0163   theDCCheader.setSrpStatus(srChStatus_);
0164   theDCCheader.setTccStatus(tccChStatus_);
0165   theDCCheader.setFEStatus(feChStatus_);
0166 
0167   theDCCheader.setSRPLv1(srpLv1_);
0168   theDCCheader.setSRPBx(srpBx_);
0169   theDCCheader.setFELv1(feLv1_);
0170   theDCCheader.setFEBx(feBx_);
0171   theDCCheader.setTCCLv1(tccLv1_);
0172   theDCCheader.setTCCBx(tccBx_);
0173 
0174   EcalDCCHeaderRuntypeDecoder theRuntypeDecoder;
0175   unsigned int DCCruntype = runType_;
0176   unsigned int DCCdetTriggerType = detailedTriggerType_;
0177   theRuntypeDecoder.Decode(triggerType_, DCCdetTriggerType, DCCruntype, &theDCCheader);
0178 
0179   // Add Header to collection
0180   (*dccHeaders_)->push_back(theDCCheader);
0181 }
0182 
0183 void DCCEventBlock::display(std::ostream& o) {
0184   o << "\n Unpacked Info for DCC Event Class"
0185     << "\n DW1 ============================="
0186     << "\n Fed Id " << fedId_ << "\n Bx " << bx_ << "\n L1 " << l1_ << "\n Trigger Type " << triggerType_
0187     << "\n DW2 ============================="
0188     << "\n Length " << blockLength_ << "\n Dcc errors " << dccErrors_ << "\n Run number " << runNumber_
0189     << "\n DW3 ============================="
0190     << "\n SR " << sr_ << "\n ZS " << zs_ << "\n TZS " << tzs_ << "\n SRStatus " << srChStatus_;
0191 
0192   std::vector<short>::iterator it;
0193   int i(0), k(0);
0194   for (it = tccChStatus_.begin(); it != tccChStatus_.end(); it++, i++) {
0195     o << "\n TCCStatus#" << i << " " << (*it);
0196   }
0197 
0198   i = 0;
0199   for (it = feChStatus_.begin(); it != feChStatus_.end(); it++, i++) {
0200     if (!(i % 14)) {
0201       o << "\n DW" << (k + 3) << " =============================";
0202       k++;
0203     }
0204     o << "\n FEStatus#" << i << " " << (*it);
0205   }
0206 
0207   o << "\n";
0208 }
0209 
0210 DCCEventBlock::~DCCEventBlock() {
0211   if (towerBlock_) {
0212     delete towerBlock_;
0213   }
0214   if (tccBlock_) {
0215     delete tccBlock_;
0216   }
0217   if (memBlock_) {
0218     delete memBlock_;
0219   }
0220   if (srpBlock_) {
0221     delete srpBlock_;
0222   }
0223 }
0224 
0225 // -----------------------------------------------------------------------
0226 // sync checking
0227 
0228 bool isSynced(const unsigned int dccBx,
0229               const unsigned int bx,
0230               const unsigned int dccL1,
0231               const unsigned int l1,
0232               const BlockType type,
0233               const unsigned int fov) {
0234   // avoid checking for MC until EcalDigiToRaw bugfixed
0235   // and to guarantee backward compatibility on RAW data
0236   if (fov < 1)
0237     return true;
0238   // check the BX sync according the following rule:
0239   //
0240   //   FE Block     MEM Block     TCC Block  SRP Block  DCC
0241   // ------------------------------------------------------------------
0242   //   fe_bx     == mem_bx == 0   tcc_bx ==  srp_bx ==  DCC_bx == 3564
0243   //   fe_bx     == mem_bx     == tcc_bx ==  srp_bx ==  DCC_bx != 3564
0244 
0245   const bool bxSynced = ((type == FE_MEM) && (bx == 0) && (dccBx == 3564)) ||
0246                         ((type == FE_MEM) && (bx == dccBx) && (dccBx != 3564)) || ((type == TCC_SRP) && (bx == dccBx));
0247 
0248   // check the L1A sync:
0249   //
0250   // L1A counter relation is valid modulo 0xFFF:
0251   // fe_l1  == mem_l1 == (DCC_l1-1) & 0xFFF
0252   // tcc_l1 == srp_l1 ==  DCC_l1    & 0xFFF
0253 
0254   const bool l1Synced =
0255       ((type == FE_MEM) && (l1 == ((dccL1 - 1) & 0xFFF))) || ((type == TCC_SRP) && (l1 == (dccL1 & 0xFFF)));
0256 
0257   return (bxSynced && l1Synced);
0258 }