Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-18 03:41:50

0001 #ifndef CondFormats_HGCalObjects_interface_HGCalMappingParameterIndex_h
0002 #define CondFormats_HGCalObjects_interface_HGCalMappingParameterIndex_h
0003 
0004 #include <cstdint>
0005 #include <vector>
0006 #include <map>
0007 #include <algorithm>  // for std::min
0008 #include <utility>    // for std::pair, std::make_pair
0009 #include <iterator>   // for std::next and std::advance
0010 
0011 #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
0012 #include "CondFormats/Serialization/interface/Serializable.h"
0013 #include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h"
0014 #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h"
0015 #include "FWCore/Utilities/interface/Exception.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 
0018 /**
0019    @short this structure holds the indices and types in the readout sequence
0020    as the 12 capture blocks may not all be used and the each capture block may also be under-utilized
0021    a lookup table is used to hold the compact index
0022  */
0023 struct HGCalFEDReadoutSequence {
0024   uint32_t id;
0025   ///>look-up table (capture block, econd idx) -> internal dense index
0026   std::vector<int> moduleLUT_;
0027   ///>dense sequence of modules in the readout: the type is the one in use in the cell mapping
0028   std::vector<int> readoutTypes_;
0029   ///>dense sequence of offsets for modules, e-Rx and channel data
0030   std::vector<uint32_t> modOffsets_, erxOffsets_, chDataOffsets_, enabledErx_;
0031   COND_SERIALIZABLE;
0032 };
0033 
0034 /**
0035    @short utility class to assign dense readout module indexing
0036    the class holds the information on the expected readout sequence (module types) per FED and their offset in the SoAs of data
0037  */
0038 class HGCalMappingModuleIndexer {
0039 public:
0040   HGCalMappingModuleIndexer() : modFedIndexer_({maxCBperFED_, maxECONDperCB_}) {}
0041 
0042   ~HGCalMappingModuleIndexer() = default;
0043 
0044   /**
0045      @short for a new module it adds it's type to the readaout sequence vector
0046      if the fed id is not yet existing in the mapping it's added
0047      a dense indexer is used to create the necessary indices for the new module
0048      unused indices will be set with -1
0049    */
0050   void processNewModule(uint32_t fedid,
0051                         uint16_t captureblockIdx,
0052                         uint16_t econdIdx,
0053                         uint32_t typecodeIdx,
0054                         uint32_t nerx,
0055                         uint32_t nwords,
0056                         std::string const &typecode);
0057 
0058   /**
0059      @short to be called after all the modules have been processed
0060    */
0061   void finalize();
0062 
0063   /**
0064      @short decodes silicon or sipm type and cell type for the detector id 
0065      from the typecode string
0066    */
0067   static std::pair<bool, int> convertTypeCode(std::string_view typecode) {
0068     if (typecode.size() < 5)
0069       throw cms::Exception("InvalidHGCALTypeCode") << typecode << " is invalid for decoding readout cell type";
0070     bool isSiPM = {typecode.find("TM") != std::string::npos ? true : false};
0071     int celltype;
0072     if (isSiPM) {
0073       celltype = 0;  // Assign SiPM type coarse or molded with next version of modulelocator
0074     } else {
0075       celltype = {typecode[4] == '1' ? 0 : typecode[4] == '2' ? 1 : 2};
0076     }
0077     return std::pair<bool, bool>(isSiPM, celltype);
0078   }
0079 
0080   /**
0081      @short returns the index for the n-th module in the readout sequence of a FED
0082      if the index in the readout sequence is unknown alternative methods which take the (capture block, econd idx) are provided
0083      which will find first what should be the internal dense index (index in the readout sequence)
0084    */
0085   uint32_t getIndexForModule(uint32_t fedid, uint32_t modid) const {
0086     return fedReadoutSequences_[fedid].modOffsets_[modid];
0087   };
0088   uint32_t getIndexForModule(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx) const {
0089     uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx);
0090     return getIndexForModule(fedid, modid);
0091   };
0092   //uint32_t getIndexForModule(HGCalElectronicsId id) const {
0093   //  return getIndexForModule(id.localFEDId(),id.captureBlock(),id.econdIdx());
0094   //};
0095   uint32_t getIndexForModule(std::string const &typecode) const {
0096     const auto &[fedid, modId] = getIndexForFedAndModule(typecode);  // (fedId,modId)
0097     return getIndexForModule(fedid, modId);
0098   };
0099   uint32_t getIndexForModuleErx(uint32_t fedid, uint32_t modid, uint32_t erxidx) const {
0100     return fedReadoutSequences_[fedid].erxOffsets_[modid] + erxidx;
0101   };
0102   uint32_t getIndexForModuleErx(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx, uint32_t erxidx) const {
0103     uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx);
0104     return getIndexForModuleErx(fedid, modid, erxidx);
0105   }
0106   uint32_t getIndexForModuleData(uint32_t fedid, uint32_t modid, uint32_t erxidx, uint32_t chidx) const {
0107     return fedReadoutSequences_[fedid].chDataOffsets_[modid] + erxidx * HGCalMappingCellIndexer::maxChPerErx_ + chidx;
0108   };
0109   uint32_t getIndexForModuleData(
0110       uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx, uint32_t erxidx, uint32_t chidx) const {
0111     uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx);
0112     return getIndexForModuleData(fedid, modid, erxidx, chidx);
0113   };
0114   uint32_t getIndexForModuleData(HGCalElectronicsId id) const {
0115     return id.isCM() ? getIndexForModuleErx(id.localFEDId(), id.captureBlock(), id.econdIdx(), id.econdeRx())
0116                      : getIndexForModuleData(
0117                            id.localFEDId(), id.captureBlock(), id.econdIdx(), id.econdeRx(), id.halfrocChannel());
0118   };
0119   uint32_t getIndexForModuleData(std::string typecode) const {
0120     const auto &[fedid, modid] = getIndexForFedAndModule(typecode);
0121     return getIndexForModuleData(fedid, modid, 0, 0);
0122   };
0123   std::pair<uint32_t, uint32_t> getIndexForFedAndModule(std::string const &typecode) const;
0124 
0125   /**
0126      @short return number maximum index of FED, ECON-D Module, eRx ROC
0127    */
0128   uint32_t getNFED() const {  // return total number of FEDs that actually exist
0129     return count_if(fedReadoutSequences_.begin(), fedReadoutSequences_.end(), [](auto fedrs) {
0130       return fedrs.readoutTypes_.size() != 0;
0131     });
0132   }
0133   uint32_t getMaxFEDSize() const { return fedReadoutSequences_.size(); }
0134   uint32_t getMaxModuleSize() const {
0135     return maxModulesIdx_;
0136   }  // total number of ECON-Ds (useful for setting ECON-D SoA size)
0137   uint32_t getMaxModuleSize(uint32_t fedid) const {  // number of ECON-Ds for given FED id
0138     return fedReadoutSequences_[fedid].readoutTypes_.size();
0139   }
0140   uint32_t getMaxERxSize() const {
0141     return maxErxIdx_;
0142   }  // total number of eRx half-ROCs (useful for setting config SoA size)
0143   uint32_t getMaxERxSize(uint32_t fedid, uint32_t modid) const {  // number of eRx half-ROCs for given FED & ECON-D ids
0144     auto modtype_val = fedReadoutSequences_[fedid].readoutTypes_[modid];
0145     return globalTypesNErx_[modtype_val];
0146   }
0147   uint32_t getMaxDataSize() const {
0148     return maxDataIdx_;
0149   }  // total number of channels (useful for setting calib SoA size)
0150 
0151   /**
0152      @short return type ECON-D Module
0153    */
0154   int getTypeForModule(uint32_t fedid, uint32_t modid) const {
0155     return fedReadoutSequences_[fedid].readoutTypes_[modid];
0156   }
0157   int getTypeForModule(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx) const {
0158     uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx);
0159     return getTypeForModule(fedid, modid);
0160   }
0161 
0162   /**
0163      @short getters for private members
0164    */
0165   HGCalDenseIndexerBase const &getFEDIndexer() const { return modFedIndexer_; }
0166   std::vector<HGCalFEDReadoutSequence> const &getFEDReadoutSequences() const { return fedReadoutSequences_; }
0167   std::vector<uint32_t> const &getGlobalTypesCounter() const { return globalTypesCounter_; }
0168   std::vector<uint32_t> const &getGlobalTypesNErx() const { return globalTypesNErx_; }
0169   std::vector<uint32_t> const &getGlobalTypesNWords() const { return globalTypesNWords_; }
0170   std::vector<uint32_t> const &getModuleOffsets() const { return moduleOffsets_; }
0171   std::vector<uint32_t> const &getErxOffsets() const { return erxOffsets_; }
0172   std::vector<uint32_t> const &getDataOffsets() const { return dataOffsets_; }
0173   uint32_t fedCount() const { return nfeds_; }
0174   uint32_t maxDataIndex() const { return maxDataIdx_; }
0175   uint32_t maxErxIndex() const { return maxErxIdx_; }
0176   uint32_t maxModulesIndex() const { return maxModulesIdx_; }
0177   std::map<std::string, std::pair<uint32_t, uint32_t>> const &getTypecodeMap() const { return typecodeMap_; }
0178 
0179   ///< max number of main buffers/capture blocks per FED
0180   constexpr static uint32_t maxCBperFED_ = 10;
0181   ///< max number of ECON-Ds processed by a main buffer/capture block
0182   constexpr static uint32_t maxECONDperCB_ = 12;
0183 
0184 private:
0185   ///< internal indexer
0186   HGCalDenseIndexerBase modFedIndexer_;
0187   ///< the sequence of FED readout sequence descriptors
0188   std::vector<HGCalFEDReadoutSequence> fedReadoutSequences_;
0189   ///< global counters for types of modules, number of e-Rx and words
0190   std::vector<uint32_t> globalTypesCounter_, globalTypesNErx_, globalTypesNWords_;
0191   ///< base offsets to apply per module type with different granularity : module, e-Rx, channel data
0192   std::vector<uint32_t> moduleOffsets_, erxOffsets_, dataOffsets_;
0193   ///< global counters (sizes of vectors)
0194   uint32_t nfeds_, maxDataIdx_, maxErxIdx_, maxModulesIdx_;
0195   ///< map from module type code string to (fedIdx,modIdx) pair (implemented to retrieve dense index offset)
0196   std::map<std::string, std::pair<uint32_t, uint32_t>> typecodeMap_;
0197 
0198   /**
0199      @short given capture block and econd indices returns the dense indexer
0200    */
0201   uint32_t denseIndexingFor(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx) const {
0202     if (fedid > nfeds_)
0203       throw cms::Exception("ValueError") << "FED ID=" << fedid << " is unknown to current mapping";
0204     uint32_t idx = modFedIndexer_.denseIndex({{captureblockIdx, econdIdx}});
0205     auto dense_idx = fedReadoutSequences_[fedid].moduleLUT_[idx];
0206     if (dense_idx < 0)
0207       throw cms::Exception("ValueError") << "FED ID=" << fedid << " capture block=" << captureblockIdx
0208                                          << " econ=" << econdIdx << "has not been assigned a dense indexing"
0209                                          << std::endl;
0210     return uint32_t(dense_idx);
0211   }
0212 
0213   /**
0214      @short when finalize is called, empty entries are removed and they may need to be re-assigned for the real final number of modules
0215    */
0216   void reassignTypecodeLocation(uint32_t fedid, uint32_t cur_modIdx, uint32_t new_modIx) {
0217     std::pair<uint32_t, uint32_t> val(fedid, cur_modIdx), newval(fedid, new_modIx);
0218 
0219     for (auto it : typecodeMap_) {
0220       if (it.second != val)
0221         continue;
0222       typecodeMap_[it.first] = newval;
0223       break;
0224     }
0225   }
0226 
0227   COND_SERIALIZABLE;
0228 };
0229 
0230 #endif