Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:11:47

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h"
0003 #include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h"       // for HGCSiliconDetId::waferType
0004 #include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h"  // for HGCScintillatorDetId::tileGranularity
0005 
0006 /**
0007  * @short for a new module it adds it's type to the readaout sequence vector
0008  * if the fed id is not yet existing in the mapping it's added
0009  * a dense indexer is used to create the necessary indices for the new module
0010  * unused indices will be set with -1
0011  */
0012 void HGCalMappingModuleIndexer::processNewModule(uint32_t fedid,
0013                                                  uint16_t captureblockIdx,
0014                                                  uint16_t econdIdx,
0015                                                  uint32_t typecodeIdx,
0016                                                  uint32_t nerx,
0017                                                  uint32_t nwords,
0018                                                  std::string const& typecode) {
0019   //add fed if needed
0020   if (fedid >= fedReadoutSequences_.size()) {
0021     fedReadoutSequences_.resize(fedid + 1);
0022   }
0023   HGCalFEDReadoutSequence& frs = fedReadoutSequences_[fedid];
0024   frs.id = fedid;
0025 
0026   //assign position, resize if needed, and fill the type code
0027   uint32_t idx = modFedIndexer_.denseIndex({{captureblockIdx, econdIdx}});
0028   if (idx >= frs.readoutTypes_.size()) {
0029     frs.readoutTypes_.resize(idx + 1, -1);
0030   }
0031   frs.readoutTypes_[idx] = typecodeIdx;
0032 
0033   //count another typecodein the global list
0034   if (typecodeIdx >= globalTypesCounter_.size()) {
0035     globalTypesCounter_.resize(typecodeIdx + 1, 0);
0036     globalTypesNErx_.resize(typecodeIdx + 1, 0);
0037     globalTypesNWords_.resize(typecodeIdx + 1, 0);
0038     dataOffsets_.resize(typecodeIdx + 1, 0);
0039   }
0040   globalTypesCounter_[typecodeIdx]++;
0041   globalTypesNErx_[typecodeIdx] = nerx;
0042   globalTypesNWords_[typecodeIdx] = nwords;
0043 
0044   //add typecode string to map to retrieve fedId & modId later
0045   if (!typecode.empty()) {
0046     if (typecodeMap_.find(typecode) != typecodeMap_.end()) {     // found key
0047       const auto& [fedid_, modid_] = typecodeMap_.at(typecode);  // (fedId,modId)
0048       edm::LogWarning("HGCalMappingModuleIndexer")
0049           << "Found typecode " << typecode << " already in map (fedid,modid)=(" << fedid_ << "," << modid_
0050           << ")! Overwriting with (" << fedid << "," << idx << ")...";
0051     }
0052     LogDebug("HGCalMappingModuleIndexer")
0053         << "HGCalMappingModuleIndexer::processNewModule: Adding typecode=\"" << typecode << "\" with fedid=" << fedid
0054         << ", idx=" << idx << " (will be re-indexed after finalize)";
0055     typecodeMap_[typecode] = std::make_pair(fedid, idx);
0056   }
0057 }
0058 
0059 /// @short to be called after all the modules have been processed
0060 void HGCalMappingModuleIndexer::finalize() {
0061   //max indices at different levels
0062   nfeds_ = fedReadoutSequences_.size();
0063   maxModulesIdx_ = std::accumulate(globalTypesCounter_.begin(), globalTypesCounter_.end(), 0);
0064   maxErxIdx_ = std::inner_product(globalTypesCounter_.begin(), globalTypesCounter_.end(), globalTypesNErx_.begin(), 0);
0065   maxDataIdx_ =
0066       std::inner_product(globalTypesCounter_.begin(), globalTypesCounter_.end(), globalTypesNWords_.begin(), 0);
0067 
0068   //compute the global offset to assign per board type, eRx and channel data
0069   moduleOffsets_.resize(maxModulesIdx_, 0);
0070   erxOffsets_.resize(maxModulesIdx_, 0);
0071   dataOffsets_.resize(maxModulesIdx_, 0);
0072   for (size_t i = 1; i < globalTypesCounter_.size(); i++) {
0073     moduleOffsets_[i] = globalTypesCounter_[i - 1];
0074     erxOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNErx_[i - 1];
0075     dataOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNWords_[i - 1];
0076   }
0077   std::partial_sum(moduleOffsets_.begin(), moduleOffsets_.end(), moduleOffsets_.begin());
0078   std::partial_sum(erxOffsets_.begin(), erxOffsets_.end(), erxOffsets_.begin());
0079   std::partial_sum(dataOffsets_.begin(), dataOffsets_.end(), dataOffsets_.begin());
0080 
0081   //now go through the FEDs and ascribe the offsets per module in the readout sequence
0082   std::vector<uint32_t> typeCounters(globalTypesCounter_.size(), 0);
0083   for (auto& fedit : fedReadoutSequences_) {
0084     //assign the final indexing in the look-up table depending on which ECON-D's are really present
0085     size_t nconn(0);
0086     fedit.moduleLUT_.resize(fedit.readoutTypes_.size(), -1);
0087     for (size_t i = 0; i < fedit.readoutTypes_.size(); i++) {
0088       if (fedit.readoutTypes_[i] == -1)
0089         continue;  //unexisting
0090 
0091       reassignTypecodeLocation(fedit.id, i, nconn);
0092       fedit.moduleLUT_[i] = nconn;
0093       nconn++;
0094     }
0095 
0096     //remove unexisting ECONs building a final compact readout sequence
0097     fedit.readoutTypes_.erase(
0098         std::remove_if(
0099             fedit.readoutTypes_.begin(), fedit.readoutTypes_.end(), [&](int val) -> bool { return val == -1; }),
0100         fedit.readoutTypes_.end());
0101 
0102     //resize vectors to their final size and set final values
0103     size_t nmods = fedit.readoutTypes_.size();
0104     fedit.modOffsets_.resize(nmods, 0);
0105     fedit.erxOffsets_.resize(nmods, 0);
0106     fedit.chDataOffsets_.resize(nmods, 0);
0107     fedit.enabledErx_.resize(nmods, 0);
0108 
0109     for (size_t i = 0; i < nmods; i++) {
0110       int type_val = fedit.readoutTypes_[i];
0111 
0112       //module offset : global offset for this type + current index for this type
0113       uint32_t baseMod_offset = moduleOffsets_[type_val] + typeCounters[type_val];
0114       fedit.modOffsets_[i] = baseMod_offset;  // + internalMod_offset;
0115 
0116       //erx-level offset : global offset of e-Rx of this type + #e-Rrx * current index for this type
0117       uint32_t baseErx_offset = erxOffsets_[type_val];
0118       uint32_t internalErx_offset = globalTypesNErx_[type_val] * typeCounters[type_val];
0119       fedit.erxOffsets_[i] = baseErx_offset + internalErx_offset;
0120 
0121       //channel data offset: global offset for data of this type + #words * current index for this type
0122       uint32_t baseData_offset = dataOffsets_[type_val];
0123       uint32_t internalData_offset = globalTypesNWords_[type_val] * typeCounters[type_val];
0124       fedit.chDataOffsets_[i] = baseData_offset + internalData_offset;
0125 
0126       //enabled erx flags
0127       //FIXME: assume all eRx are enabled now
0128       fedit.enabledErx_[i] = (0b1 << globalTypesNErx_[type_val]) - 0b1;
0129       typeCounters[type_val]++;
0130     }
0131   }
0132 }
0133 
0134 /**
0135  * @short decode silicon or sipm type and cell type for the detector id 
0136  * from the typecode string: "M[LH]-X[123]X-*" for Si, "T[LH]-L*S*[PN]" for SiPm
0137  */
0138 std::pair<bool, int8_t> HGCalMappingModuleIndexer::getCellType(std::string_view typecode) {
0139   if (typecode.size() < 5) {
0140     cms::Exception ex("InvalidHGCALTypeCode");
0141     ex << "'" << typecode << "' is invalid for decoding readout cell type";
0142     ex.addContext("Calling HGCalMappingModuleIndexer::getCellType()");
0143     throw ex;
0144   }
0145   int8_t celltype = -1;
0146   const bool isSiPM = (typecode[0] == 'T');
0147   const bool isHD = (typecode[1] == 'H');
0148   if (isSiPM) {  // assign SiPM type coarse or molded with next version of modulelocator
0149     if (isHD)
0150       celltype = HGCScintillatorDetId::tileGranularity::HGCalTileFine;
0151     else
0152       celltype = HGCScintillatorDetId::tileGranularity::HGCalTileNormal;
0153   } else {  // assign Si wafer type low/high density and thickness (120, 200, 300 um)
0154     const char thickness = typecode[4];
0155     if (isHD) {
0156       if (thickness == '1')
0157         celltype = HGCSiliconDetId::waferType::HGCalHD120;
0158       else if (thickness == '2')
0159         celltype = HGCSiliconDetId::waferType::HGCalHD200;
0160     } else {
0161       if (thickness == '2')
0162         celltype = HGCSiliconDetId::waferType::HGCalLD200;
0163       else if (thickness == '3')
0164         celltype = HGCSiliconDetId::waferType::HGCalLD300;
0165     }
0166   }
0167   if (celltype == -1) {
0168     cms::Exception ex("InvalidHGCALTypeCode");
0169     ex << "Could not parse cell type from typecode='" << typecode << "'";
0170     ex.addContext("Calling HGCalMappingModuleIndexer::getCellType()");
0171     throw ex;
0172   }
0173   return std::pair<bool, int8_t>(isSiPM, celltype);
0174 }
0175 
0176 //
0177 std::pair<uint32_t, uint32_t> HGCalMappingModuleIndexer::getIndexForFedAndModule(std::string const& typecode) const {
0178   auto it = typecodeMap_.find(typecode);
0179   if (it == typecodeMap_.end()) {       // did not find key
0180     std::size_t nmax = 100;             // maximum number of keys to print
0181     auto maxit = typecodeMap_.begin();  // limit printout to prevent gigantic print out
0182     std::advance(maxit, std::min(typecodeMap_.size(), nmax));
0183     std::string allkeys = std::accumulate(
0184         std::next(typecodeMap_.begin()), maxit, typecodeMap_.begin()->first, [](const std::string& a, const auto& b) {
0185           return a + ',' + b.first;
0186         });
0187     if (typecodeMap_.size() > nmax)
0188       allkeys += ", ...";
0189     throw cms::Exception("HGCalMappingModuleIndexer")
0190         << "Could not find typecode '" << typecode << "' in map (size=" << typecodeMap_.size()
0191         << ")! Found the following modules (from the module locator file): " << allkeys;
0192   }
0193   return it->second;  // (fedid,modid)
0194 };