Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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