Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:59:41

0001 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.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 DCCMemBlock::DCCMemBlock(DCCDataUnpacker* u, EcalElectronicsMapper* m, DCCEventBlock* e)
0008     : DCCDataBlockPrototype(u, m, e) {
0009   unfilteredTowerBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
0010   expXtalTSamples_ = mapper_->numbXtalTSamples();
0011 
0012   numbDWInXtalBlock_ = (expXtalTSamples_ - 2) / 4 + 1;
0013   xtalBlockSize_ = numbDWInXtalBlock_ * 8;
0014   kSamplesPerPn_ = expXtalTSamples_ * 5;
0015 
0016   unsigned int numbOfXtalBlocks = (unfilteredTowerBlockLength_ - 1) / numbDWInXtalBlock_;
0017   unsigned int numbOfPnBlocks = numbOfXtalBlocks / 5;  //change 5 by a variable
0018   unsigned int vectorSize = numbOfPnBlocks * 10 * expXtalTSamples_;
0019 
0020   //Build pnDiodevector
0021   for (unsigned int i = 0; i < vectorSize; i++) {
0022     pn_.push_back(-1);
0023   }
0024 }
0025 
0026 void DCCMemBlock::updateCollectors() {
0027   invalidMemChIds_ = unpacker_->invalidMemChIdsCollection();
0028   invalidMemBlockSizes_ = unpacker_->invalidMemBlockSizesCollection();
0029   invalidMemTtIds_ = unpacker_->invalidMemTtIdsCollection();
0030   invalidMemGains_ = unpacker_->invalidMemGainsCollection();
0031   pnDiodeDigis_ = unpacker_->pnDiodeDigisCollection();
0032 }
0033 
0034 int DCCMemBlock::unpack(const uint64_t** data, unsigned int* dwToEnd, unsigned int expectedTowerID) {
0035   error_ = false;
0036   datap_ = data;
0037   data_ = *data;
0038   dwToEnd_ = dwToEnd;
0039 
0040   if ((*dwToEnd_) < 1) {
0041     if (!DCCDataUnpacker::silentMode_) {
0042       edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0043                                         << mapper_->getActiveDCC() << "\nThe end of event was reached !";
0044     }
0045     return STOP_EVENT_UNPACKING;
0046   }
0047 
0048   lastStripId_ = 0;
0049   lastXtalId_ = 0;
0050   expTowerID_ = expectedTowerID;
0051 
0052   //Point to begin of block
0053   data_++;
0054 
0055   towerId_ = (*data_) & TOWER_ID_MASK;
0056   nTSamples_ = (*data_ >> TOWER_NSAMP_B) & TOWER_NSAMP_MASK;
0057   bx_ = (*data_ >> TOWER_BX_B) & TOWER_BX_MASK;
0058   l1_ = (*data_ >> TOWER_L1_B) & TOWER_L1_MASK;
0059   blockLength_ = (*data_ >> TOWER_LENGTH_B) & TOWER_LENGTH_MASK;
0060 
0061   event_->setFESyncNumbers(l1_, bx_, short(expectedTowerID - 1));
0062 
0063   //debugging
0064   //display(cout);
0065 
0066   // Block Length Check (1)
0067   if (unfilteredTowerBlockLength_ != blockLength_) {
0068     // chosing channel 1 as representative of a dummy...
0069     EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0070     (*invalidMemBlockSizes_)->push_back(id);
0071     if (!DCCDataUnpacker::silentMode_) {
0072       edm::LogWarning("IncorrectEvent") << "\nFor event " << event_->l1A() << ", fed " << mapper_->getActiveDCC()
0073                                         << " and tower block " << towerId_ << "\nExpected mem block size is "
0074                                         << (unfilteredTowerBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
0075                                         << " was found";
0076     }
0077     return STOP_EVENT_UNPACKING;
0078   }
0079 
0080   // Block Length Check (2)
0081   if ((*dwToEnd_) < blockLength_) {
0082     if (!DCCDataUnpacker::silentMode_) {
0083       edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0084                                         << mapper_->getActiveDCC() << "\n Only " << ((*dwToEnd_) * 8)
0085                                         << " bytes are available while " << (blockLength_ * 8) << " are needed!";
0086       // chosing channel 1 as representative of a dummy...
0087     }
0088     EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0089     (*invalidMemBlockSizes_)->push_back(id);
0090     return STOP_EVENT_UNPACKING;
0091   }
0092 
0093   // Synchronization Check
0094   if (sync_) {
0095     const unsigned int dccBx = (event_->bx()) & TOWER_BX_MASK;
0096     const unsigned int dccL1 = (event_->l1A()) & TOWER_L1_MASK;
0097     const unsigned int fov = (event_->fov()) & H_FOV_MASK;
0098 
0099     if (!isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
0100       if (!DCCDataUnpacker::silentMode_) {
0101         edm::LogWarning("IncorrectEvent")
0102             << "Synchronization error for Mem block"
0103             << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << ")\n"
0104             << "  dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
0105             << "  => Stop event unpacking";
0106       }
0107       //Note : add to error collection ?
0108       // need of a new collection
0109       return STOP_EVENT_UNPACKING;
0110     }
0111   }
0112 
0113   // Number Of Samples Check
0114   if (nTSamples_ != expXtalTSamples_) {
0115     if (!DCCDataUnpacker::silentMode_) {
0116       edm::LogWarning("IncorrectEvent") << "\nUnable to unpack MEM block for event " << event_->l1A() << " in fed "
0117                                         << mapper_->getActiveDCC() << "\nNumber of time samples " << nTSamples_
0118                                         << " is not the same as expected (" << expXtalTSamples_ << ")";
0119     }
0120     //Note : add to error collection ?
0121     return STOP_EVENT_UNPACKING;
0122   }
0123 
0124   //Channel Id Check
0125   if (expTowerID_ != towerId_) {
0126     // chosing channel 1 as representative as a dummy...
0127     EcalElectronicsId id(mapper_->getActiveSM(), expTowerID_, 1, 1);
0128     (*invalidMemTtIds_)->push_back(id);
0129     if (!DCCDataUnpacker::silentMode_) {
0130       edm::LogWarning("IncorrectBlock") << "For event " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
0131                                         << " and sm: " << mapper_->getActiveSM() << "\nExpected mem tower block is "
0132                                         << expTowerID_ << " while " << towerId_ << " was found ";
0133     }
0134 
0135     towerId_ = expTowerID_;
0136 
0137     // todo : go to the next mem
0138     error_ = true;
0139 
0140     updateEventPointers();
0141     return SKIP_BLOCK_UNPACKING;
0142   }
0143 
0144   //point to xtal data
0145   data_++;
0146 
0147   unpackMemTowerData();
0148 
0149   if (!error_) {
0150     fillPnDiodeDigisCollection();
0151   }
0152 
0153   updateEventPointers();
0154 
0155   return BLOCK_UNPACKED;
0156 }
0157 
0158 void DCCMemBlock::unpackMemTowerData() {
0159   //todo: move EcalPnDiodeDetId to electronics mapper
0160 
0161   lastTowerBeforeMem_ = 0;
0162   // differentiating the barrel and the endcap case
0163   if (9 < mapper_->getActiveSM() || mapper_->getActiveSM() < 46) {
0164     lastTowerBeforeMem_ = 69;
0165   } else {
0166     lastTowerBeforeMem_ = 69;
0167   }
0168 
0169   for (unsigned int expStripId = 1; expStripId <= 5; expStripId++) {
0170     for (unsigned int expXtalId = 1; expXtalId <= 5; expXtalId++) {
0171       const uint16_t* xData_ = reinterpret_cast<const uint16_t*>(data_);
0172 
0173       // Get xtal data ids
0174       unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
0175       unsigned int xtalId = ((*xData_) >> TOWER_XTALID_B) & TOWER_XTALID_MASK;
0176 
0177       bool errorOnDecoding(false);
0178 
0179       if (expStripId != stripId || expXtalId != xtalId) {
0180         // chosing channel and strip as EcalElectronicsId
0181         EcalElectronicsId id(mapper_->getActiveSM(), towerId_, expStripId, expXtalId);
0182         (*invalidMemChIds_)->push_back(id);
0183 
0184         if (!DCCDataUnpacker::silentMode_) {
0185           edm::LogWarning("IncorrectBlock")
0186               << "For event " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower mem block "
0187               << towerId_ << "\nThe expected strip is " << expStripId << " and " << stripId << " was found"
0188               << "\nThe expected xtal  is " << expXtalId << " and " << xtalId << " was found";
0189         }
0190 
0191         stripId = expStripId;
0192         xtalId = expXtalId;
0193 
0194         errorOnDecoding = true;
0195 
0196         //Note : move to the next ...
0197       }
0198 
0199       unsigned int ipn, index;
0200 
0201       if ((stripId - 1) % 2 == 0) {
0202         ipn = (towerId_ - lastTowerBeforeMem_) * 5 + xtalId - 1;
0203       } else {
0204         ipn = (towerId_ - lastTowerBeforeMem_) * 5 + 5 - xtalId;
0205       }
0206 
0207       //Cooking samples
0208       for (unsigned int i = 0; i < nTSamples_; i++) {
0209         xData_++;
0210 
0211         index = ipn * 50 + (stripId - 1) * nTSamples_ + i;
0212 
0213         //edm::LogDebug("EcalRawToDigiMemChId")<<"\n Strip id "<<std::dec<<stripId<<" Xtal id "<<xtalId
0214         //  <<" tsamp = "<<i<<" 16b = 0x "<<std::hex<<(*xData_)<<dec;
0215 
0216         unsigned int temp = (*xData_) & TOWER_DIGI_MASK;
0217 
0218         short sample(0);
0219 
0220         if ((stripId - 1) % 2) {
0221           // If strip number is even, 14 bits are reversed in order
0222           for (int ib = 0; ib < 14; ib++) {
0223             sample <<= 1;
0224             sample |= (temp & 1);
0225             temp >>= 1;
0226           }
0227 
0228         } else {
0229           sample = temp;
0230         }
0231 
0232         sample ^= 0x800;
0233         unsigned int gain = sample >> 12;
0234 
0235         if (gain >= 2) {
0236           EcalElectronicsId id(mapper_->getActiveSM(), towerId_, stripId, xtalId);
0237           (*invalidMemGains_)->push_back(id);
0238 
0239           if (!DCCDataUnpacker::silentMode_) {
0240             edm::LogWarning("IncorrectGain")
0241                 << "For event " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " , mem tower block "
0242                 << towerId_ << "\nIn strip " << stripId << " xtal " << xtalId << " the gain is " << gain
0243                 << " in sample " << (i + 1);
0244           }
0245 
0246           errorOnDecoding = true;
0247         }
0248 
0249         if (!errorOnDecoding && !error_) {
0250           pn_[index] = sample;
0251         }  //Note : move to the next versus flag...
0252 
0253       }  // loop over samples ended
0254 
0255       data_ += numbDWInXtalBlock_;
0256     }  //loop over xtals
0257   }    // loop over strips
0258 }
0259 
0260 void DCCMemBlock::fillPnDiodeDigisCollection() {
0261   //todo change pnId max
0262   for (int pnId = 1; pnId <= 5; pnId++) {
0263     bool errorOnPn(false);
0264     unsigned int realPnId = pnId;
0265 
0266     if (towerId_ == 70) {
0267       realPnId += 5;
0268     }
0269 
0270     // Note : we are assuming always 5 VFE channels enabled
0271     // This means we all have 5 pns per tower
0272 
0273     // solution before sending creation of PnDigi's in mapper as done with crystals
0274     //     mapper_->getActiveSM()  : this is the 'dccid'
0275     //     number ranging internally in ECAL from 1 to 54, according convention specified here:
0276     //     http://indico.cern.ch/getFile.py/access?contribId=0&resId=0&materialId=slides&confId=11621
0277 
0278     //     mapper_->getActiveDCC() : this is the FED_id (601 - 654 for ECAL at CMS)
0279 
0280     const int activeSM = mapper_->getActiveSM();
0281     int subdet(0);
0282     if (NUMB_SM_EB_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EB_PLU_MAX) {
0283       subdet = EcalBarrel;
0284     } else if ((NUMB_SM_EE_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EE_MIN_MAX) ||
0285                (NUMB_SM_EE_PLU_MIN <= activeSM && activeSM <= NUMB_SM_EE_PLU_MAX)) {
0286       subdet = EcalEndcap;
0287     } else {
0288       if (!DCCDataUnpacker::silentMode_) {
0289         edm::LogWarning("IncorrectMapping") << "\n mapper points to non existing dccid: " << activeSM;
0290       }
0291     }
0292 
0293     EcalPnDiodeDetId PnId(subdet, activeSM, realPnId);
0294 
0295     EcalPnDiodeDigi thePnDigi(PnId);
0296     thePnDigi.setSize(kSamplesPerPn_);
0297 
0298     for (unsigned int ts = 0; ts < kSamplesPerPn_; ts++) {
0299       short pnDiodeData = pn_[(towerId_ - lastTowerBeforeMem_) * 250 + (pnId - 1) * kSamplesPerPn_ + ts];
0300       if (pnDiodeData == -1) {
0301         errorOnPn = true;
0302         break;
0303       }
0304 
0305       EcalFEMSample thePnSample(pnDiodeData);
0306       thePnDigi.setSample(ts, thePnSample);
0307     }
0308 
0309     if (!errorOnPn) {
0310       (*pnDiodeDigis_)->push_back(thePnDigi);
0311     }
0312   }
0313 }
0314 
0315 void DCCMemBlock::display(std::ostream& o) {
0316   o << "\n Unpacked Info for DCC MEM Block"
0317     << "\n DW1 ============================="
0318     << "\n Mem Tower Block Id " << towerId_ << "\n Numb Samp " << nTSamples_ << "\n Bx " << bx_ << "\n L1 " << l1_
0319     << "\n blockLength " << blockLength_;
0320 }