Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-04 04:04:15

0001 #ifndef CondFormats_HGCalObjects_interface_HGCalMappingCellParameterIndex_h
0002 #define CondFormats_HGCalObjects_interface_HGCalMappingCellParameterIndex_h
0003 
0004 #include <iostream>
0005 #include <cstdint>
0006 #include <vector>
0007 #include <numeric>
0008 #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
0009 #include "CondFormats/Serialization/interface/Serializable.h"
0010 #include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h"
0011 
0012 /**
0013    @short utility class to assign dense readout cell indexing
0014  */
0015 class HGCalMappingCellIndexer {
0016 public:
0017   // typedef HGCalDenseIndexerBase WaferDenseIndexerBase;
0018 
0019   HGCalMappingCellIndexer() = default;
0020 
0021   /**
0022      adds to map of type codes (= module types) to handle and updatest the max. number of eRx 
0023    */
0024   void processNewCell(std::string typecode, uint16_t chip, uint16_t half) {
0025     //assign index to this typecode and resize the max e-Rx vector
0026     if (typeCodeIndexer_.count(typecode) == 0) {
0027       typeCodeIndexer_[typecode] = typeCodeIndexer_.size();
0028       maxErx_.resize(typeCodeIndexer_.size(), 0);
0029     }
0030 
0031     size_t idx = typeCodeIndexer_[typecode];
0032     uint16_t erx = chip * 2 + half + 1;  //use the number not the index here
0033     maxErx_[idx] = std::max(maxErx_[idx], erx);
0034   }
0035 
0036   /**
0037      @short process the current list of type codes handled and updates the dense indexers
0038   */
0039   void update() {
0040     uint32_t n = typeCodeIndexer_.size();
0041     offsets_ = std::vector<uint32_t>(n, 0);
0042     di_ = std::vector<HGCalDenseIndexerBase>(n, HGCalDenseIndexerBase(2));
0043     for (uint32_t idx = 0; idx < n; idx++) {
0044       uint16_t nerx = maxErx_[idx];
0045       di_[idx].updateRanges({{nerx, maxChPerErx_}});
0046       if (idx < n - 1)
0047         offsets_[idx + 1] = di_[idx].getMaxIndex();
0048     }
0049 
0050     //accumulate the offsets in the array
0051     std::partial_sum(offsets_.begin(), offsets_.end(), offsets_.begin());
0052   }
0053 
0054   /**
0055      @short gets index given typecode string
0056    */
0057   size_t getEnumFromTypecode(std::string typecode) const {
0058     auto it = typeCodeIndexer_.find(typecode);
0059     if (it == typeCodeIndexer_.end())
0060       throw cms::Exception("ValueError") << " unable to find typecode=" << typecode << " in cell indexer";
0061     return it->second;
0062   }
0063 
0064   /**
0065      @short checks if there is a typecode corresponding to an index
0066    */
0067   std::string getTypecodeFromEnum(size_t idx) const {
0068     for (const auto& it : typeCodeIndexer_)
0069       if (it.second == idx)
0070         return it.first;
0071     throw cms::Exception("ValueError") << " unable to find typecode corresponding to idx=" << idx;
0072   }
0073 
0074   /**
0075      @short returns the dense indexer for a typecode
0076    */
0077   HGCalDenseIndexerBase getDenseIndexFor(std::string typecode) const {
0078     return getDenseIndexerFor(getEnumFromTypecode(typecode));
0079   }
0080 
0081   /**
0082      @short returns the dense indexer for a given internal index
0083   */
0084   HGCalDenseIndexerBase getDenseIndexerFor(size_t idx) const {
0085     if (idx >= di_.size())
0086       throw cms::Exception("ValueError") << " index requested for cell dense indexer (i=" << idx
0087                                          << ") is larger than allocated";
0088     return di_[idx];
0089   }
0090 
0091   /**
0092      @short builders for the dense index
0093    */
0094   uint32_t denseIndex(std::string typecode, uint32_t chip, uint32_t half, uint32_t seq) const {
0095     return denseIndex(getEnumFromTypecode(typecode), chip, half, seq);
0096   }
0097   uint32_t denseIndex(std::string typecode, uint32_t erx, uint32_t seq) const {
0098     return denseIndex(getEnumFromTypecode(typecode), erx, seq);
0099   }
0100   uint32_t denseIndex(size_t idx, uint32_t chip, uint32_t half, uint32_t seq) const {
0101     uint16_t erx = chip * maxHalfPerROC_ + half;
0102     return denseIndex(idx, erx, seq);
0103   }
0104   uint32_t denseIndex(size_t idx, uint32_t erx, uint32_t seq) const {
0105     return di_[idx].denseIndex({{erx, seq}}) + offsets_[idx];
0106   }
0107 
0108   /**
0109      @short decodes the dense index code
0110    */
0111   uint32_t elecIdFromIndex(uint32_t rtn, std::string typecode) const {
0112     return elecIdFromIndex(rtn, getEnumFromTypecode(typecode));
0113   }
0114   uint32_t elecIdFromIndex(uint32_t rtn, size_t idx) const {
0115     if (idx >= di_.size())
0116       throw cms::Exception("ValueError") << " index requested for cell dense indexer (i=" << idx
0117                                          << ") is larger than allocated";
0118     rtn -= offsets_[idx];
0119     auto rtn_codes = di_[idx].unpackDenseIndex(rtn);
0120     return HGCalElectronicsId(false, 0, 0, 0, rtn_codes[0], rtn_codes[1]).raw();
0121   }
0122 
0123   /**
0124      @short returns the max. dense index expected
0125    */
0126   uint32_t maxDenseIndex() const {
0127     size_t i = maxErx_.size();
0128     if (i == 0)
0129       return 0;
0130     return offsets_.back() + maxErx_.back() * maxChPerErx_;
0131   }
0132 
0133   /**
0134      @short gets the number of words for a given typecode
0135   */
0136   size_t getNWordsExpectedFor(std::string typecode) const {
0137     auto it = getEnumFromTypecode(typecode);
0138     return getNWordsExpectedFor(it);
0139   }
0140   size_t getNWordsExpectedFor(size_t typecodeidx) const { return maxErx_[typecodeidx] * maxChPerErx_; }
0141 
0142   /**
0143      @short gets the number of e-Rx for a given typecode
0144   */
0145   size_t getNErxExpectedFor(std::string typecode) const {
0146     auto it = getEnumFromTypecode(typecode);
0147     return getNErxExpectedFor(it);
0148   }
0149   size_t getNErxExpectedFor(size_t typecodeidx) const { return maxErx_[typecodeidx]; }
0150 
0151   constexpr static char maxHalfPerROC_ = 2;
0152   constexpr static uint16_t maxChPerErx_ = 37;  //36 channels + 1 calib
0153 
0154   std::map<std::string, size_t> typeCodeIndexer_;
0155   std::vector<uint16_t> maxErx_;
0156   std::vector<uint32_t> offsets_;
0157   std::vector<HGCalDenseIndexerBase> di_;
0158 
0159   ~HGCalMappingCellIndexer() {}
0160 
0161   COND_SERIALIZABLE;
0162 };
0163 
0164 #endif