diff --git a/CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h b/CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h index 4b9a3b3d1ab69..1d15c65546d5d 100644 --- a/CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h +++ b/CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h @@ -45,7 +45,7 @@ class HGCalDenseIndexerBase { return codes; } - uint32_t getMaxIndex() const { return maxIdx_; } + uint32_t maxIndex() const { return maxIdx_; } ~HGCalDenseIndexerBase() = default; diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h b/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h index 1a49875a7eb06..3f72620e4a907 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h @@ -19,9 +19,9 @@ class HGCalMappingCellIndexer { HGCalMappingCellIndexer() = default; /** - adds to map of type codes (= module types) to handle and updatest the max. number of eRx + adds to map of type codes (= module types) to handle and updatest the max. number of eRx */ - void processNewCell(std::string typecode, uint16_t chip, uint16_t half) { + void processNewCell(std::string const& typecode, uint16_t chip, uint16_t half) { //assign index to this typecode and resize the max e-Rx vector if (typeCodeIndexer_.count(typecode) == 0) { typeCodeIndexer_[typecode] = typeCodeIndexer_.size(); @@ -44,17 +44,14 @@ class HGCalMappingCellIndexer { uint16_t nerx = maxErx_[idx]; di_[idx].updateRanges({{nerx, maxChPerErx_}}); if (idx < n - 1) - offsets_[idx + 1] = di_[idx].getMaxIndex(); + offsets_[idx + 1] = di_[idx].maxIndex() + offsets_[idx]; } - - //accumulate the offsets in the array - std::partial_sum(offsets_.begin(), offsets_.end(), offsets_.begin()); } /** @short gets index given typecode string */ - size_t getEnumFromTypecode(std::string typecode) const { + size_t getEnumFromTypecode(std::string const& typecode) const { auto it = typeCodeIndexer_.find(typecode); if (it == typeCodeIndexer_.end()) throw cms::Exception("ValueError") << " unable to find typecode=" << typecode << " in cell indexer"; @@ -74,7 +71,7 @@ class HGCalMappingCellIndexer { /** @short returns the dense indexer for a typecode */ - HGCalDenseIndexerBase getDenseIndexFor(std::string typecode) const { + HGCalDenseIndexerBase getDenseIndexFor(std::string const& typecode) const { return getDenseIndexerFor(getEnumFromTypecode(typecode)); } @@ -91,10 +88,10 @@ class HGCalMappingCellIndexer { /** @short builders for the dense index */ - uint32_t denseIndex(std::string typecode, uint32_t chip, uint32_t half, uint32_t seq) const { + uint32_t denseIndex(std::string const& typecode, uint32_t chip, uint32_t half, uint32_t seq) const { return denseIndex(getEnumFromTypecode(typecode), chip, half, seq); } - uint32_t denseIndex(std::string typecode, uint32_t erx, uint32_t seq) const { + uint32_t denseIndex(std::string const& typecode, uint32_t erx, uint32_t seq) const { return denseIndex(getEnumFromTypecode(typecode), erx, seq); } uint32_t denseIndex(size_t idx, uint32_t chip, uint32_t half, uint32_t seq) const { @@ -108,7 +105,7 @@ class HGCalMappingCellIndexer { /** @short decodes the dense index code */ - uint32_t elecIdFromIndex(uint32_t rtn, std::string typecode) const { + uint32_t elecIdFromIndex(uint32_t rtn, std::string const& typecode) const { return elecIdFromIndex(rtn, getEnumFromTypecode(typecode)); } uint32_t elecIdFromIndex(uint32_t rtn, size_t idx) const { @@ -133,7 +130,7 @@ class HGCalMappingCellIndexer { /** @short gets the number of words for a given typecode */ - size_t getNWordsExpectedFor(std::string typecode) const { + size_t getNWordsExpectedFor(std::string const& typecode) const { auto it = getEnumFromTypecode(typecode); return getNWordsExpectedFor(it); } @@ -142,7 +139,7 @@ class HGCalMappingCellIndexer { /** @short gets the number of e-Rx for a given typecode */ - size_t getNErxExpectedFor(std::string typecode) const { + size_t getNErxExpectedFor(std::string const& typecode) const { auto it = getEnumFromTypecode(typecode); return getNErxExpectedFor(it); } @@ -151,7 +148,7 @@ class HGCalMappingCellIndexer { constexpr static char maxHalfPerROC_ = 2; constexpr static uint16_t maxChPerErx_ = 37; //36 channels + 1 calib - std::map typeCodeIndexer_; + std::unordered_map typeCodeIndexer_; std::vector maxErx_; std::vector offsets_; std::vector di_; diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h b/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h new file mode 100644 index 0000000000000..2f29f9b95b1a1 --- /dev/null +++ b/CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h @@ -0,0 +1,156 @@ +#ifndef CondFormats_HGCalObjects_interface_HGCalMappingCellIndexerTrigger_h +#define CondFormats_HGCalObjects_interface_HGCalMappingCellIndexerTrigger_h + +#include +#include +#include +#include +#include "CondFormats/Serialization/interface/Serializable.h" +#include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h" + +/** + @short utility class to assign dense readout trigger cell indexing + */ +class HGCalMappingCellIndexerTrigger { +public: + // typedef HGCalDenseIndexerBase WaferDenseIndexerBase; + + HGCalMappingCellIndexerTrigger() = default; + + /** + adds to map of type codes (= module types) to handle and updatest the max. number of eRx + */ + void processNewCell(std::string const& typecode, uint16_t ROC, uint16_t trLink, uint16_t trCell) { + // Skip if trLink, trCell not connected + if (trLink == uint16_t(-1) || trCell == uint16_t(-1)) + return; + //assign index to this typecode and resize the max vectors + if (typeCodeIndexer_.count(typecode) == 0) { + typeCodeIndexer_[typecode] = typeCodeIndexer_.size(); + maxROC_.resize(typeCodeIndexer_.size(), 0); + maxTrLink_.resize(typeCodeIndexer_.size(), 0); + maxTCPerLink_.resize(typeCodeIndexer_.size(), 0); + } + + size_t idx = typeCodeIndexer_[typecode]; + + /*High density modules have links {0, 2} and low {0, 1, 2, 3} so to make it work I need to divide by 2*/ + if (typecode[1] == 'H') + trLink /= 2; + /*SiPM tiles have trCells indexed from 1 instead from 0*/ + if (typecode[0] == 'T') + trCell--; + maxROC_[idx] = std::max(maxROC_[idx], static_cast(ROC + 1)); + maxTrLink_[idx] = std::max(maxTrLink_[idx], static_cast(trLink + 1)); + maxTCPerLink_[idx] = std::max(maxTCPerLink_[idx], static_cast(trCell + 1)); + } + + /** + @short process the current list of type codes handled and updates the dense indexers + */ + void update() { + uint32_t n = typeCodeIndexer_.size(); + offsets_ = std::vector(n, 0); + di_ = std::vector(n, HGCalDenseIndexerBase(3)); /* The indices are {ROC, trLink, TC}*/ + for (uint32_t idx = 0; idx < n; idx++) { + uint16_t maxROCs = maxROC_[idx]; + uint16_t maxLinks = maxTrLink_[idx]; + uint16_t maxTCPerLink = maxTCPerLink_[idx]; + di_[idx].updateRanges({{maxROCs, maxLinks, maxTCPerLink}}); + if (idx < n - 1) + offsets_[idx + 1] = di_[idx].maxIndex() + offsets_[idx]; + } + } + + /** + @short gets index given typecode string + */ + size_t getEnumFromTypecode(std::string const& typecode) const { + auto it = typeCodeIndexer_.find(typecode); + if (it == typeCodeIndexer_.end()) + throw cms::Exception("ValueError") << " unable to find typecode=" << typecode << " in cell indexer"; + return it->second; + } + + /** + @short checks if there is a typecode corresponding to an index + */ + std::string getTypecodeFromEnum(size_t idx) const { + for (const auto& it : typeCodeIndexer_) + if (it.second == idx) + return it.first; + throw cms::Exception("ValueError") << " unable to find typecode corresponding to idx=" << idx; + } + + /** + @short returns the dense indexer for a typecode + */ + HGCalDenseIndexerBase getDenseIndexFor(std::string const& typecode) const { + return getDenseIndexerFor(getEnumFromTypecode(typecode)); + } + + /** + @short returns the dense indexer for a given internal index + */ + HGCalDenseIndexerBase getDenseIndexerFor(size_t idx) const { + if (idx >= di_.size()) + throw cms::Exception("ValueError") << " index requested for cell dense indexer (i=" << idx + << ") is larger than allocated"; + return di_[idx]; + } + + /** + @short builders for the dense index + */ + uint16_t denseIndex(std::string const& typecode, uint32_t ROC, uint32_t trLink, uint32_t trCell) const { + return denseIndex(getEnumFromTypecode(typecode), ROC, trLink, trCell); + } + uint32_t denseIndex(size_t idx, uint32_t ROC, uint32_t trLink, uint32_t trCell) const { + return di_[idx].denseIndex({{ROC, trLink, trCell}}) + offsets_[idx]; + } + + /** + @short returns the max. dense index expected + */ + uint32_t maxDenseIndex() const { + size_t i = maxTrLink_.size(); + if (i == 0) + return 0; + return offsets_.back() + maxROC_.back() * maxTrLink_.back() * maxTCPerLink_.back(); + } + + /** + @short gets the number of words (cells) for a given typecode + Note : some partials are rounded to the closest multiplie of 16 or 8 depending on the density + That is done because not all the TrigLinks,TrgCells possible are assigned in practice + e.g.: ML-T has 22 TCs but this will return 32 or MH-T has 19 but it will return 24 + It results in a small mem overhead over the totall memory needed to be allocated + */ + size_t getNWordsExpectedFor(std::string const& typecode) const { + auto it = getEnumFromTypecode(typecode); + return getNWordsExpectedFor(it); + } + size_t getNWordsExpectedFor(size_t typecodeidx) const { return getDenseIndexerFor(typecodeidx).maxIndex(); } + + /** + @short gets the number of Trigger Links for a given typecode + */ + size_t getNTrLinkExpectedFor(std::string const& typecode) const { + auto it = getEnumFromTypecode(typecode); + return getNTrLinkExpectedFor(it); + } + size_t getNTrLinkExpectedFor(size_t typecodeidx) const { return maxTrLink_[typecodeidx] * maxROC_[typecodeidx]; } + + std::unordered_map typeCodeIndexer_; + std::vector maxROC_; + std::vector maxTrLink_; + std::vector maxTCPerLink_; + std::vector offsets_; + std::vector di_; + + ~HGCalMappingCellIndexerTrigger() = default; + + COND_SERIALIZABLE; +}; + +#endif diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h index 25092c4a5dc80..0a72843a8dfd0 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h @@ -62,7 +62,7 @@ class HGCalMappingModuleIndexer { void finalize(); /** - * @short decode silicon or sipm type and cell type for the detector id + * @short decode silicon or sipm type and cell type for the detector id * from the typecode string: "M[LH]-X[123]X-*" for Si, "T[LH]-L*S*[PN]" for SiPm */ static std::pair getCellType(std::string_view typecode); @@ -115,21 +115,21 @@ class HGCalMappingModuleIndexer { /** * @short return number maximum index of FED, ECON-D Module, eRx ROC */ - uint32_t getNumFEDs() const { + uint32_t numFEDs() const { return count_if(fedReadoutSequences_.begin(), fedReadoutSequences_.end(), [](auto fedrs) { return fedrs.readoutTypes_.size() != 0; }); } ///< return total number of FEDs that actually exist - uint32_t getMaxFEDSize() const { + uint32_t maxFEDSize() const { return fedReadoutSequences_.size(); } ///< maximum FED index (fedReadoutSequences_ includes non existing FED IDs) - uint32_t getMaxModuleSize() const { + uint32_t maxModuleSize() const { return maxModulesIdx_; } ///< total number of ECON-Ds (useful for setting ECON-D SoA size) uint32_t getNumModules(uint32_t fedid) const { return fedReadoutSequences_[fedid].readoutTypes_.size(); } ///< number of ECON-Ds for given FED id - uint32_t getMaxERxSize() const { + uint32_t maxERxSize() const { return maxErxIdx_; } ///< total number of eRx half-ROCs (useful for setting config SoA size) uint32_t getNumERxs(uint32_t fedid, uint32_t modid) const { @@ -140,7 +140,7 @@ class HGCalMappingModuleIndexer { const auto &[fedid, modid] = getIndexForFedAndModule(typecode); return getNumERxs(fedid, modid); } ///< number of eRx half-ROCs for a given ECON-D typecode - uint32_t getMaxDataSize() const { + uint32_t maxDataSize() const { return maxDataIdx_; } ///< total number of channels (useful for setting calib SoA size) uint32_t getNumChannels(uint32_t fedid, uint32_t modid) const { @@ -165,19 +165,19 @@ class HGCalMappingModuleIndexer { /** * @short getters for private members */ - HGCalDenseIndexerBase const &getFEDIndexer() const { return modFedIndexer_; } - std::vector const &getFEDReadoutSequences() const { return fedReadoutSequences_; } - std::vector const &getGlobalTypesCounter() const { return globalTypesCounter_; } - std::vector const &getGlobalTypesNErx() const { return globalTypesNErx_; } - std::vector const &getGlobalTypesNWords() const { return globalTypesNWords_; } - std::vector const &getModuleOffsets() const { return moduleOffsets_; } - std::vector const &getErxOffsets() const { return erxOffsets_; } - std::vector const &getDataOffsets() const { return dataOffsets_; } + HGCalDenseIndexerBase const &fedIndexer() const { return modFedIndexer_; } + std::vector const &fedReadoutSequences() const { return fedReadoutSequences_; } + std::vector const &globalTypesCounter() const { return globalTypesCounter_; } + std::vector const &globalTypesNErx() const { return globalTypesNErx_; } + std::vector const &globalTypesNWords() const { return globalTypesNWords_; } + std::vector const &moduleOffsets() const { return moduleOffsets_; } + std::vector const &erxOffsets() const { return erxOffsets_; } + std::vector const &dataOffsets() const { return dataOffsets_; } uint32_t fedCount() const { return nfeds_; } uint32_t maxDataIndex() const { return maxDataIdx_; } uint32_t maxErxIndex() const { return maxErxIdx_; } uint32_t maxModulesIndex() const { return maxModulesIdx_; } - std::map> const &getTypecodeMap() const { return typecodeMap_; } + std::map> const &typecodeMap() const { return typecodeMap_; } /// max number of main buffers/capture blocks per FED constexpr static uint32_t maxCBperFED_ = 10; diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h new file mode 100644 index 0000000000000..b877077ab13ad --- /dev/null +++ b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h @@ -0,0 +1,230 @@ +#ifndef CondFormats_HGCalObjects_interface_HGCalMappingModuleIndexerTrigger_h +#define CondFormats_HGCalObjects_interface_HGCalMappingModuleIndexerTrigger_h + +#include +#include +#include +#include // for std::min +#include // for std::pair, std::make_pair +#include // for std::next and std::advance + +#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "CondFormats/Serialization/interface/Serializable.h" +#include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h" +#include "FWCore/Utilities/interface/Exception.h" + +/** + * @short this structure holds the indices and types in the readout sequence + * as the 12 capture blocks may not all be used and the each capture block may also be under-utilized + * a lookup table is used to hold the compact index + */ +struct HGCalTriggerFEDReadoutSequence { + uint32_t id; + /// look-up table (capture block, econd idx) -> internal dense index + std::vector moduleLUT_; + /// dense sequence of modules in the readout: the type is the one in use in the cell mapping + std::vector readoutTypes_; + /// dense sequence of offsets for modules, e-Rx and channel data + std::vector modOffsets_, TrLinkOffsets_, TCOffsets_, enabledLink_; + COND_SERIALIZABLE; +}; + +/** + * @short utility class to assign dense readout module indexing + * the class holds the information on the expected readout sequence (module types) per FED and their offset in the SoAs of data + */ +class HGCalMappingModuleIndexerTrigger { +public: + HGCalMappingModuleIndexerTrigger() : modFedIndexer_({maxECONTperFED_, 1}) {} + + ~HGCalMappingModuleIndexerTrigger() = default; + + /** + * @short for a new module it adds it's type to the readaout sequence vector + * if the fed id is not yet existing in the mapping it's added + * a dense indexer is used to create the necessary indices for the new module + * unused indices will be set with -1 + */ + void processNewModule(uint32_t fedid, + uint16_t econtIdx, + uint32_t typecodeIdx, + uint32_t nTrLinks, + uint32_t nTCs, + std::string const &typecode); + + /** + * @short to be called after all the modules have been processed + */ + void finalize(); + + /** + * @short decode silicon or sipm type and cell type for the detector id + * from the typecode string: "M[LH]-X[123]X-*" for Si, "T[LH]-L*S*[PN]" for SiPm + */ + static std::pair getCellType(std::string_view typecode); + + /** + * @short returns the index for the n-th module in the readout sequence of a FED + * if the index in the readout sequence is unknown alternative methods which take the (capture block, econd idx) are provided + * which will find first what should be the internal dense index (index in the readout sequence) + */ + uint32_t getIndexForModule(uint32_t fedid, uint32_t modid) const { + return fedReadoutSequences_[fedid].modOffsets_[modid]; + }; + uint32_t getIndexForModule(uint32_t fedid, uint16_t econtIdx) const { + uint32_t modid = denseIndexingFor(fedid, econtIdx); + return getIndexForModule(fedid, modid); + }; + uint32_t getIndexForModule(std::string const &typecode) const { + const auto &[fedid, modid] = getIndexForFedAndModule(typecode); // (fedId,modId) + return getIndexForModule(fedid, modid); + }; + + uint32_t getIndexForModuleTrLink(uint32_t fedid, uint32_t modid, uint32_t trLinkidx) const { + return fedReadoutSequences_[fedid].TrLinkOffsets_[modid] + trLinkidx; + }; + uint32_t getIndexForModuleTrLink(uint32_t fedid, uint16_t econtIdx, uint32_t trLinkidx) const { + uint32_t modid = denseIndexingFor(fedid, econtIdx); + return getIndexForModuleTrLink(fedid, modid, trLinkidx); + } + + uint32_t getIndexForModuleData(uint32_t fedid, uint32_t modid, uint32_t trLinkidx, uint32_t TCidx) const { + uint32_t denseTCidx = getDenseTCIndex(fedid, modid, trLinkidx, TCidx); + return getIndexForModuleData(fedid, modid, denseTCidx); + }; + uint32_t getIndexForModuleData(uint32_t fedid, uint16_t econtIdx, uint32_t trLinkidx, uint32_t TCidx) const { + uint32_t modid = denseIndexingFor(fedid, econtIdx); + return getIndexForModuleData(fedid, modid, trLinkidx, TCidx); + }; + uint32_t getIndexForModuleData(uint32_t fedid, uint32_t modid, uint32_t denseTCidx) const { + return fedReadoutSequences_[fedid].TCOffsets_[modid] + denseTCidx; + }; + uint32_t getIndexForModuleData(std::string const &typecode) const { + const auto &[fedid, modid] = getIndexForFedAndModule(typecode); + return getIndexForModuleData(fedid, modid, 0, 0); + }; + std::pair getIndexForFedAndModule(std::string const &typecode) const; + + uint32_t getDenseTCIndex(uint32_t fedid, uint32_t modid, uint32_t trLinkidx, uint32_t TCidx) const { + int typecodeidx = getTypeForModule(fedid, modid); + return getDenseTCIndex(typecodeidx, trLinkidx, TCidx); + }; + uint32_t getDenseTCIndex(int typecodeidx, uint32_t trLinkidx, uint32_t TCidx) const { + return trLinkidx * (globalTypesNTCs_[typecodeidx] / globalTypesNTrLinks_[typecodeidx]) + TCidx; + }; + + /** + * @short return number maximum index of FED, ECON-D Module, eRx ROC + */ + uint32_t numFEDs() const { + return count_if(fedReadoutSequences_.begin(), fedReadoutSequences_.end(), [](auto fedrs) { + return fedrs.readoutTypes_.size() != 0; + }); + } ///< return total number of FEDs that actually exist + uint32_t maxFEDSize() const { + return fedReadoutSequences_.size(); + } ///< maximum FED index (fedReadoutSequences_ includes non existing FED IDs) + uint32_t maxModuleSize() const { + return maxModulesIdx_; + } ///< total number of ECON-Ds (useful for setting ECON-D SoA size) + uint32_t getNumModules(uint32_t fedid) const { + return fedReadoutSequences_[fedid].readoutTypes_.size(); + } ///< number of ECON-Ds for given FED id + uint32_t maxTrLinkSize() const { + return maxTrLinksIdx_; + } ///< total number of eRx half-ROCs (useful for setting config SoA size) + uint32_t getNumTrLinks(uint32_t fedid, uint32_t modid) const { + auto modtype_val = fedReadoutSequences_[fedid].readoutTypes_[modid]; + return globalTypesNTrLinks_[modtype_val]; + } ///< number of eRx half-ROCs for given FED & ECON-D ids + uint32_t getNumTrLinks(std::string const &typecode) const { + const auto &[fedid, modid] = getIndexForFedAndModule(typecode); + return getNumTrLinks(fedid, modid); + } ///< number of eRx half-ROCs for a given ECON-D typecode + uint32_t maxDataSize() const { return maxNTCIdx_; } ///< total number of channels (useful for setting calib SoA size) + + uint32_t getNumChannels(uint32_t fedid, uint32_t modid) const { + auto modtype_val = fedReadoutSequences_[fedid].readoutTypes_[modid]; + return globalTypesNTCs_[modtype_val]; + } ///< total number of channels for given FED & ECON-D ids + uint32_t getNumChannels(std::string const &typecode) const { + const auto &[fedid, modid] = getIndexForFedAndModule(typecode); + return getNumChannels(fedid, modid); + } ///< total number of channels for a given ECON-D typecode + + /** + * @short return type ECON-D Module + */ + int getTypeForModule(uint32_t fedid, uint32_t modid) const { + return fedReadoutSequences_[fedid].readoutTypes_[modid]; + } + int getTypeForModule(uint32_t fedid, uint16_t econtIdx) const { + uint32_t modid = denseIndexingFor(fedid, econtIdx); + return getTypeForModule(fedid, modid); + } + + /** + * @short getters for private members + */ + HGCalDenseIndexerBase const &fedIndexer() const { return modFedIndexer_; } + std::vector const &fedReadoutSequences() const { return fedReadoutSequences_; } + std::vector const &globalTypesCounter() const { return globalTypesCounter_; } + std::vector const &globalTypesNTrLinks() const { return globalTypesNTrLinks_; } + std::vector const &globalTypesNTCs() const { return globalTypesNTCs_; } + std::vector const &moduleOffsets() const { return offsetsModule_; } + std::vector const &trLinkOffsets() const { return offsetsTrLink_; } + std::vector const &trCellOffsets() const { return offsetsTC_; } + uint32_t fedCount() const { return nfeds_; } + uint32_t maxDataIndex() const { return maxNTCIdx_; } + uint32_t maxTrLinkIndex() const { return maxTrLinksIdx_; } + uint32_t maxModulesIndex() const { return maxModulesIdx_; } + std::map> const &typecodeMap() const { return typecodeMap_; } + + // max number of ECON-Ds processed by a main buffer/capture block + constexpr static uint32_t maxECONTperFED_ = 12; + +private: + // internal indexer + HGCalDenseIndexerBase modFedIndexer_; + // the sequence of FED readout sequence descriptors + std::vector fedReadoutSequences_; + // global counters for types of modules, number of e-Rx and words + std::vector globalTypesCounter_, globalTypesNTrLinks_, globalTypesNTCs_; + // base offsets to apply per module type with different granularity : module, e-Rx, channel data + std::vector offsetsModule_, offsetsTrLink_, offsetsTC_; + // global counters (sizes of vectors) + uint32_t nfeds_, maxNTCIdx_, maxTrLinksIdx_, maxModulesIdx_; + // map from module type code string to (fedIdx,modIdx) pair (implemented to retrieve dense index offset) + std::map> typecodeMap_; + + /** + * @short given capture block and econd indices returns the dense indexer + */ + uint32_t denseIndexingFor(uint32_t fedid, uint16_t econtIdx) const { + if (fedid > nfeds_) + throw cms::Exception("ValueError") << "FED ID=" << fedid << " is unknown to current mapping"; + uint32_t idx = modFedIndexer_.denseIndex({{econtIdx, 0}}); + auto dense_idx = fedReadoutSequences_[fedid].moduleLUT_[idx]; + if (dense_idx < 0) + throw cms::Exception("ValueError") << "FED ID=" << fedid << " econ=" << econtIdx + << "has not been assigned a dense indexing" << std::endl; + return uint32_t(dense_idx); + } + + /** + * @short when finalize is called, empty entries are removed and they may need to be re-assigned for the real final number of modules + */ + void reassignTypecodeLocation(uint32_t fedid, uint32_t cur_modIdx, uint32_t new_modIx) { + std::pair val(fedid, cur_modIdx), newval(fedid, new_modIx); + for (const auto &it : typecodeMap_) { + if (it.second != val) + continue; + typecodeMap_[it.first] = newval; + break; + } + } + + COND_SERIALIZABLE; +}; + +#endif diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h b/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h index f814c0db22cf6..43e6a1f2bfc7c 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h @@ -9,12 +9,18 @@ namespace hgcal { // SoA with channel-level module mapping parameters in host memory: using HGCalMappingModuleParamHost = PortableHostCollection; + // SoA with channel-level module mapping parameters in host memory: + using HGCalMappingModuleTriggerParamHost = PortableHostCollection; + // SoA with channel-level cell mapping parameters in host memory for both Si and SiPM channels: using HGCalMappingCellParamHost = PortableHostCollection; //SoA with detailed indices corresponding to the dense index in use using HGCalDenseIndexInfoHost = PortableHostCollection; + //SoA with detailed indices corresponding to the dense index in use for the trigger + using HGCalDenseIndexTriggerInfoHost = PortableHostCollection; + } // namespace hgcal #endif // CondFormats_HGCalObjects_interface_HGCalMappingParameterHost_h diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h b/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h index 1574d778fd1c3..c7368e8b2a51f 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h @@ -26,9 +26,29 @@ namespace hgcal { SOA_COLUMN(uint16_t, econdidx), SOA_COLUMN(uint16_t, captureblockidx), SOA_COLUMN(uint32_t, eleid), - SOA_COLUMN(uint32_t, detid)) + SOA_COLUMN(uint32_t, detid), + SOA_COLUMN(uint32_t, cassette)) using HGCalMappingModuleParamSoA = HGCalMappingModuleParamSoALayout<>; + // Generate structure of module-level (ECON-T) arrays (SoA) layout with module mapping information + GENERATE_SOA_LAYOUT(HGCalMappingModuleTriggerParamSoALayout, + SOA_COLUMN(bool, valid), + SOA_COLUMN(bool, zside), + SOA_COLUMN(bool, isSiPM), + SOA_COLUMN(int, plane), + SOA_COLUMN(int, i1), + SOA_COLUMN(int, i2), + SOA_COLUMN(uint8_t, irot), + SOA_COLUMN(int, celltype), + SOA_COLUMN(uint16_t, typeidx), + SOA_COLUMN(uint16_t, fedid), + SOA_COLUMN(uint16_t, slinkidx), + SOA_COLUMN(uint16_t, econtidx), + SOA_COLUMN(uint32_t, muxid), + SOA_COLUMN(uint32_t, trigdetid), + SOA_COLUMN(uint32_t, cassette)) + using HGCalMappingModuleTriggerParamSoA = HGCalMappingModuleTriggerParamSoALayout<>; + // Generate structure of channel-level arrays (SoA) layout with cell mapping information for both silicon and SiPM GENERATE_SOA_LAYOUT(HGCalMappingCellParamSoALayout, SOA_COLUMN(bool, valid), @@ -69,6 +89,20 @@ namespace hgcal { SOA_COLUMN(float, z)) using HGCalDenseIndexInfoSoA = HGCalDenseIndexInfoSoALayout<>; + // Generatie structure of tirgger-cell level arrays (SoA) layout with module mapping info + GENERATE_SOA_LAYOUT(HGCalDenseIndexTriggerInfoSoALayout, + SOA_COLUMN(uint32_t, fedId), + SOA_COLUMN(uint16_t, fedReadoutSeq), + SOA_COLUMN(uint32_t, trigdetid), + SOA_COLUMN(uint32_t, muxid), + SOA_COLUMN(uint32_t, modInfoIdx), + SOA_COLUMN(uint32_t, cellInfoIdx), + SOA_COLUMN(uint32_t, TCNumber), + SOA_COLUMN(float, x), + SOA_COLUMN(float, y), + SOA_COLUMN(float, z)) + using HGCalDenseIndexTriggerInfoSoA = HGCalDenseIndexTriggerInfoSoALayout<>; + } // namespace hgcal #endif // CondFormats_HGCalObjects_interface_HGCalMappingParameterSoA_h diff --git a/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h b/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h index 4df23ca3c1d24..57105136792b0 100644 --- a/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h +++ b/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h @@ -11,12 +11,16 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { namespace hgcal { using HGCalMappingModuleParamDevice = PortableCollection<::hgcal::HGCalMappingModuleParamSoA>; + using HGCalMappingModuleTriggerParamDevice = PortableCollection<::hgcal::HGCalMappingModuleTriggerParamSoA>; using HGCalMappingCellParamDevice = PortableCollection<::hgcal::HGCalMappingCellParamSoA>; using HGCalDenseIndexInfoDevice = PortableCollection<::hgcal::HGCalDenseIndexInfoSoA>; + using HGCalDenseIndexTriggerInfoDevice = PortableCollection<::hgcal::HGCalDenseIndexTriggerInfoSoA>; using HGCalMappingModuleParamHost = ::hgcal::HGCalMappingModuleParamHost; + using HGCalMappingModuleTriggerParamHost = ::hgcal::HGCalMappingModuleTriggerParamHost; using HGCalMappingCellParamHost = ::hgcal::HGCalMappingCellParamHost; using HGCalDenseIndexInfoHost = ::hgcal::HGCalDenseIndexInfoHost; + using HGCalDenseIndexTriggerInfoHost = ::hgcal::HGCalDenseIndexTriggerInfoHost; } // namespace hgcal diff --git a/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexer.cc b/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexer.cc index ebf60191e0295..5b43ab38c3e04 100644 --- a/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexer.cc +++ b/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexer.cc @@ -70,13 +70,10 @@ void HGCalMappingModuleIndexer::finalize() { erxOffsets_.resize(maxModulesIdx_, 0); dataOffsets_.resize(maxModulesIdx_, 0); for (size_t i = 1; i < globalTypesCounter_.size(); i++) { - moduleOffsets_[i] = globalTypesCounter_[i - 1]; - erxOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNErx_[i - 1]; - dataOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNWords_[i - 1]; + moduleOffsets_[i] = globalTypesCounter_[i - 1] + moduleOffsets_[i - 1]; + erxOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNErx_[i - 1] + erxOffsets_[i - 1]; + dataOffsets_[i] = globalTypesCounter_[i - 1] * globalTypesNWords_[i - 1] + dataOffsets_[i - 1]; } - std::partial_sum(moduleOffsets_.begin(), moduleOffsets_.end(), moduleOffsets_.begin()); - std::partial_sum(erxOffsets_.begin(), erxOffsets_.end(), erxOffsets_.begin()); - std::partial_sum(dataOffsets_.begin(), dataOffsets_.end(), dataOffsets_.begin()); //now go through the FEDs and ascribe the offsets per module in the readout sequence std::vector typeCounters(globalTypesCounter_.size(), 0); diff --git a/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexerTrigger.cc b/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexerTrigger.cc new file mode 100644 index 0000000000000..9b17745b2e58e --- /dev/null +++ b/CondFormats/HGCalObjects/src/HGCalMappingModuleIndexerTrigger.cc @@ -0,0 +1,192 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" // for HGCSiliconDetId::waferType +#include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" // for HGCScintillatorDetId::tileGranularity + +/** + * @short for a new module it adds its type to the readout sequence vector + * if the fed id is not yet existing in the mapping it is added + * a dense indexer is used to create the necessary indices for the new module + * unused indices will be set with -1 + */ +void HGCalMappingModuleIndexerTrigger::processNewModule(uint32_t fedid, + uint16_t econtIdx, + uint32_t typecodeIdx, + uint32_t nTrLinks, + uint32_t nTCs, + std::string const& typecode) { + // add fed if needed + if (fedid >= fedReadoutSequences_.size()) { + fedReadoutSequences_.resize(fedid + 1); + } + HGCalTriggerFEDReadoutSequence& frs = fedReadoutSequences_[fedid]; + frs.id = fedid; + + // asin position, resize if needed, and fill the type code + uint32_t idx = modFedIndexer_.denseIndex({{econtIdx, 0}}); // This will give back the econt*1+0 = econt + if (idx >= frs.readoutTypes_.size()) { + frs.readoutTypes_.resize(idx + 1, -1); + } + frs.readoutTypes_[idx] = typecodeIdx; + + // std::count another typecodein the global list + if (typecodeIdx >= globalTypesCounter_.size()) { + globalTypesCounter_.resize(typecodeIdx + 1, 0); + globalTypesNTrLinks_.resize(typecodeIdx + 1, 0); + globalTypesNTCs_.resize(typecodeIdx + 1, 0); + offsetsTC_.resize(typecodeIdx + 1, 0); + } + globalTypesCounter_[typecodeIdx]++; + globalTypesNTrLinks_[typecodeIdx] = nTrLinks; + globalTypesNTCs_[typecodeIdx] = nTCs; + + // add typecode string to map to retrieve fedId & modId later + if (!typecode.empty()) { + if (typecodeMap_.find(typecode) != typecodeMap_.end()) { // found key + const auto& [fedid_, modid_] = typecodeMap_.at(typecode); // (fedId,modId) + edm::LogWarning("HGCalMappingModuleIndexerTrigger") + << "Found typecode " << typecode << " already in map (fedid,modid)=(" << fedid_ << "," << modid_ + << ")! Overwriting with (" << fedid << "," << idx << ")..."; + } + LogDebug("HGCalMappingModuleIndexerTrigger") + << "HGCalMappingModuleIndexerTrigger::processNewModule: Adding typecode=\"" << typecode + << "\" with fedid=" << fedid << ", idx=" << idx << " (will be re-indexed after finalize)"; + typecodeMap_[typecode] = std::make_pair(fedid, idx); + } +} + +// @short to be called after all the modules have been processed +void HGCalMappingModuleIndexerTrigger::finalize() { + // max indices at different levels + nfeds_ = fedReadoutSequences_.size(); + maxModulesIdx_ = std::accumulate(globalTypesCounter_.begin(), globalTypesCounter_.end(), 0); + maxTrLinksIdx_ = + std::inner_product(globalTypesCounter_.begin(), globalTypesCounter_.end(), globalTypesNTrLinks_.begin(), 0); + maxNTCIdx_ = std::inner_product(globalTypesCounter_.begin(), globalTypesCounter_.end(), globalTypesNTCs_.begin(), 0); + + // compute the global offset to assign per board type, eRx and channel data + offsetsModule_.resize(maxModulesIdx_, 0); + offsetsTrLink_.resize(maxModulesIdx_, 0); + offsetsTC_.resize(maxModulesIdx_, 0); + for (size_t i = 1; i < globalTypesCounter_.size(); i++) { + offsetsModule_[i] = globalTypesCounter_[i - 1] + offsetsModule_[i - 1]; + offsetsTrLink_[i] = globalTypesCounter_[i - 1] * globalTypesNTrLinks_[i - 1] + offsetsTrLink_[i - 1]; + offsetsTC_[i] = globalTypesCounter_[i - 1] * globalTypesNTCs_[i - 1] + offsetsTC_[i - 1]; + } + + // now go through the FEDs and ascribe the offsets per module in the readout sequence + std::vector typeCounters(globalTypesCounter_.size(), 0); + for (auto& fedit : fedReadoutSequences_) { + // assign the final indexing in the look-up table depending on which ECON-D's are really present + size_t nconn(0); + fedit.moduleLUT_.resize(fedit.readoutTypes_.size(), -1); + for (size_t i = 0; i < fedit.readoutTypes_.size(); i++) { + if (fedit.readoutTypes_[i] == -1) + continue; //unexisting + + reassignTypecodeLocation(fedit.id, i, nconn); + fedit.moduleLUT_[i] = nconn; + nconn++; + } + + // remove unexisting ECONs building a final compact readout sequence + fedit.readoutTypes_.erase( + std::remove_if( + fedit.readoutTypes_.begin(), fedit.readoutTypes_.end(), [&](int val) -> bool { return val == -1; }), + fedit.readoutTypes_.end()); + + // resize vectors to their final size and set final values + size_t nmods = fedit.readoutTypes_.size(); + fedit.modOffsets_.resize(nmods, 0); + fedit.TrLinkOffsets_.resize(nmods, 0); + fedit.TCOffsets_.resize(nmods, 0); + fedit.enabledLink_.resize(nmods, 0); + + for (size_t i = 0; i < nmods; i++) { + int type_val = fedit.readoutTypes_[i]; + + // module offset : global offset for this type + current index for this type + uint32_t baseMod_offset = offsetsModule_[type_val] + typeCounters[type_val]; + fedit.modOffsets_[i] = baseMod_offset; // + internalMod_offset; + + // erx-level offset : global offset of e-Rx of this type + #e-Rrx * current index for this type + uint32_t baseTrLink_offset = offsetsTrLink_[type_val]; + uint32_t internalTrLink_offset = globalTypesNTrLinks_[type_val] * typeCounters[type_val]; + fedit.TrLinkOffsets_[i] = baseTrLink_offset + internalTrLink_offset; + + // channel data offset: global offset for data of this type + #words * current index for this type + uint32_t baseData_offset = offsetsTC_[type_val]; + uint32_t internalData_offset = globalTypesNTCs_[type_val] * typeCounters[type_val]; + fedit.TCOffsets_[i] = baseData_offset + internalData_offset; + + // enabled erx flags : we assume all eRx are enabled + // this results in a small mem overhead for a few partial wafers but it's not a show stopper + fedit.enabledLink_[i] = (0b1 << globalTypesNTrLinks_[type_val]) - 0b1; + typeCounters[type_val]++; + } + } +} + +/** + * @short decode silicon or sipm type and cell type for the detector id + * from the typecode string: "M[LH]-X[123]X-*" for Si, "T[LH]-L*S*[PN]" for SiPm + * details can be found in the EDMS documents under https://edms.cern.ch/document/2718867/1 + */ +std::pair HGCalMappingModuleIndexerTrigger::getCellType(std::string_view typecode) { + if (typecode.size() < 5) { + cms::Exception ex("InvalidHGCALTypeCode"); + ex << "'" << typecode << "' is invalid for decoding readout cell type"; + ex.addContext("Calling HGCalMappingModuleIndexerTrigger::getCellType()"); + throw ex; + } + int8_t celltype = -1; + const bool isSiPM = (typecode[0] == 'T'); + const bool isHD = (typecode[1] == 'H'); + if (isSiPM) { // assign SiPM type coarse or molded with next version of modulelocator + if (isHD) + celltype = HGCScintillatorDetId::tileGranularity::HGCalTileFine; + else + celltype = HGCScintillatorDetId::tileGranularity::HGCalTileNormal; + } else { // assign Si wafer type low/high density and thickness (120, 200, 300 um) + const char thickness = typecode[4]; + if (isHD) { + if (thickness == '1') + celltype = HGCSiliconDetId::waferType::HGCalHD120; + else if (thickness == '2') + celltype = HGCSiliconDetId::waferType::HGCalHD200; + } else { + if (thickness == '2') + celltype = HGCSiliconDetId::waferType::HGCalLD200; + else if (thickness == '3') + celltype = HGCSiliconDetId::waferType::HGCalLD300; + } + } + if (celltype == -1) { + cms::Exception ex("InvalidHGCALTypeCode"); + ex << "Could not parse cell type from typecode='" << typecode << "'"; + ex.addContext("Calling HGCalMappingModuleIndexerTrigger::getCellType()"); + throw ex; + } + return std::pair(isSiPM, celltype); +} + +// +std::pair HGCalMappingModuleIndexerTrigger::getIndexForFedAndModule( + std::string const& typecode) const { + auto it = typecodeMap_.find(typecode); + if (it == typecodeMap_.end()) { // did not find key + std::size_t nmax = 100; // maximum number of keys to print + auto maxit = typecodeMap_.begin(); // limit printout to prevent gigantic print out + std::advance(maxit, std::min(typecodeMap_.size(), nmax)); + std::string allkeys = std::accumulate( + std::next(typecodeMap_.begin()), maxit, typecodeMap_.begin()->first, [](const std::string& a, const auto& b) { + return a + ',' + b.first; + }); + if (typecodeMap_.size() > nmax) + allkeys += ", ..."; + throw cms::Exception("HGCalMappingModuleIndexerTrigger") + << "Could not find typecode '" << typecode << "' in map (size=" << typecodeMap_.size() + << ")! Found the following modules (from the module locator file): " << allkeys; + } + return it->second; // (fedid,modid) +}; diff --git a/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc b/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc index 1c74c1972ab5f..70ca1741904ac 100644 --- a/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc +++ b/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc @@ -2,5 +2,7 @@ #include "FWCore/Utilities/interface/typelookup.h" TYPELOOKUP_DATA_REG(hgcal::HGCalMappingModuleParamHost); +TYPELOOKUP_DATA_REG(hgcal::HGCalMappingModuleTriggerParamHost); TYPELOOKUP_DATA_REG(hgcal::HGCalMappingCellParamHost); TYPELOOKUP_DATA_REG(hgcal::HGCalDenseIndexInfoHost); +TYPELOOKUP_DATA_REG(hgcal::HGCalDenseIndexTriggerInfoHost); diff --git a/CondFormats/HGCalObjects/src/T_EventSetup_HGCalMappingIndexers.cc b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalMappingIndexers.cc index 3a34e1ec49427..c358a8761c3d8 100644 --- a/CondFormats/HGCalObjects/src/T_EventSetup_HGCalMappingIndexers.cc +++ b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalMappingIndexers.cc @@ -1,8 +1,12 @@ #include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" #include "FWCore/Utilities/interface/typelookup.h" TYPELOOKUP_DATA_REG(HGCalDenseIndexerBase); TYPELOOKUP_DATA_REG(HGCalMappingCellIndexer); TYPELOOKUP_DATA_REG(HGCalMappingModuleIndexer); +TYPELOOKUP_DATA_REG(HGCalMappingCellIndexerTrigger); +TYPELOOKUP_DATA_REG(HGCalMappingModuleIndexerTrigger); diff --git a/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc b/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc index fb851b66eb8fe..d08f6da05e0a9 100644 --- a/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc +++ b/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc @@ -2,5 +2,7 @@ #include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h" TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingModuleParamDevice); +TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingModuleTriggerParamDevice); TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingCellParamDevice); TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalDenseIndexInfoDevice); +TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalDenseIndexTriggerInfoDevice); diff --git a/CondFormats/HGCalObjects/src/classes_def.xml b/CondFormats/HGCalObjects/src/classes_def.xml index 77358db8c0808..6aa6fe55399bd 100644 --- a/CondFormats/HGCalObjects/src/classes_def.xml +++ b/CondFormats/HGCalObjects/src/classes_def.xml @@ -8,6 +8,15 @@ + + + + + + + + + @@ -15,6 +24,13 @@ + + + + + + + @@ -22,6 +38,13 @@ + + + + + + + diff --git a/CondFormats/HGCalObjects/src/headers.h b/CondFormats/HGCalObjects/src/headers.h index 69b1d81aad368..e0761918129a0 100644 --- a/CondFormats/HGCalObjects/src/headers.h +++ b/CondFormats/HGCalObjects/src/headers.h @@ -2,3 +2,5 @@ #include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" diff --git a/CondFormats/HGCalObjects/test/testDenseIndexerBase.cc b/CondFormats/HGCalObjects/test/testDenseIndexerBase.cc index 5bd1af4acb2be..d8433b618e732 100644 --- a/CondFormats/HGCalObjects/test/testDenseIndexerBase.cc +++ b/CondFormats/HGCalObjects/test/testDenseIndexerBase.cc @@ -35,10 +35,10 @@ int main() { } //check that all values were unique - assert(allidx.size() == di.getMaxIndex()); + assert(allidx.size() == di.maxIndex()); //check that values were sequential (last value==size) - assert((*allidx.end()) == di.getMaxIndex()); + assert((*allidx.end()) == di.maxIndex()); return 0; } diff --git a/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc b/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc index aa6bfa4c577a5..6196c781d3ebf 100644 --- a/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc +++ b/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc @@ -7,6 +7,9 @@ int main() { testSerialization(); testSerialization(); testSerialization(); + testSerialization(); + testSerialization(); + testSerialization(); return 0; } diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiTriggerHost.h b/DataFormats/HGCalDigi/interface/HGCalDigiTriggerHost.h new file mode 100644 index 0000000000000..1dad90b4f861a --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalDigiTriggerHost.h @@ -0,0 +1,14 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalDigiTriggerHost_h +#define DataFormats_HGCalDigi_interface_HGCalDigiTriggerHost_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiTriggerSoA.h" + +namespace hgcaldigi { + + // SoA with x, y, z, id fields in host memory + using HGCalDigiTriggerHost = PortableHostCollection; + +} // namespace hgcaldigi + +#endif // DataFormats_HGCalDigi_interface_HGCalDigiTriggerHost_h diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiTriggerSoA.h b/DataFormats/HGCalDigi/interface/HGCalDigiTriggerSoA.h new file mode 100644 index 0000000000000..1d550e975ca6b --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalDigiTriggerSoA.h @@ -0,0 +1,36 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalDigiTriggerSoA_h +#define DataFormats_HGCalDigi_interface_HGCalDigiTriggerSoA_h + +#include +#include + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" + +namespace hgcaldigi { + // Generate structure of arrays (SoA) layout with Digi dataformat + GENERATE_SOA_LAYOUT(HGCalDigiTriggerSoALayout, + SOA_COLUMN(uint8_t, algo), + SOA_COLUMN(bool, valid), + SOA_COLUMN(uint8_t, BXm3_location), + SOA_COLUMN(uint8_t, BXm2_location), + SOA_COLUMN(uint8_t, BXm1_location), + SOA_COLUMN(uint8_t, BX0_location), + SOA_COLUMN(uint8_t, BXp1_location), + SOA_COLUMN(uint8_t, BXp2_location), + SOA_COLUMN(uint8_t, BXp3_location), + SOA_COLUMN(uint16_t, BXm3_energy), + SOA_COLUMN(uint16_t, BXm2_energy), + SOA_COLUMN(uint16_t, BXm1_energy), + SOA_COLUMN(uint16_t, BX0_energy), + SOA_COLUMN(uint16_t, BXp1_energy), + SOA_COLUMN(uint16_t, BXp2_energy), + SOA_COLUMN(uint16_t, BXp3_energy), + SOA_COLUMN(uint16_t, flags), + SOA_COLUMN(uint16_t, layer), + SOA_COLUMN(uint16_t, moduleIdx)) + using HGCalDigiTriggerSoA = HGCalDigiTriggerSoALayout<>; + +} // namespace hgcaldigi + +#endif // DataFormats_HGCalDigi_interface_HGCalDigiTriggerSoA_h diff --git a/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiTriggerDevice.h b/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiTriggerDevice.h new file mode 100644 index 0000000000000..6d3738147b440 --- /dev/null +++ b/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiTriggerDevice.h @@ -0,0 +1,23 @@ +#ifndef DataFormats_HGCalDigi_interface_alpaka_HGCalDigiTriggerDevice_h +#define DataFormats_HGCalDigi_interface_alpaka_HGCalDigiTriggerDevice_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiTriggerSoA.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcaldigi { + + // make the names from the top-level hgcaldigi namespace visible for unqualified lookup + // inside the ALPAKA_ACCELERATOR_NAMESPACE::hgcaldigi namespace + using namespace ::hgcaldigi; + + // SoA in device global memory + using HGCalDigiTriggerDevice = PortableCollection; + + } // namespace hgcaldigi + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif // DataFormats_HGCalDigi_interface_alpaka_HGCalDigiTriggerDevice_h diff --git a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc index 9fb06dbfd1213..d073d20b8e6a0 100644 --- a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc +++ b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc @@ -91,8 +91,8 @@ void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) //const auto& cellIndexer = iSetup.getData(cellIndexToken_); const auto& config = iSetup.getData(configToken_); - hgcaldigi::HGCalDigiHost digis(moduleIndexer.getMaxDataSize(), cms::alpakatools::host()); - hgcaldigi::HGCalECONDPacketInfoHost econdPacketInfo(moduleIndexer.getMaxModuleSize(), cms::alpakatools::host()); + hgcaldigi::HGCalDigiHost digis(moduleIndexer.maxDataSize(), cms::alpakatools::host()); + hgcaldigi::HGCalECONDPacketInfoHost econdPacketInfo(moduleIndexer.maxModuleSize(), cms::alpakatools::host()); hgcaldigi::HGCalFEDPacketInfoHost fedPacketInfo(moduleIndexer.fedCount(), cms::alpakatools::host()); // retrieve the FED raw data @@ -105,7 +105,7 @@ void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) //serial unpacking calls if (doSerial_) { for (unsigned fedId = 0; fedId < moduleIndexer.fedCount(); ++fedId) { - const auto& frs = moduleIndexer.getFEDReadoutSequences()[fedId]; + const auto& frs = moduleIndexer.fedReadoutSequences()[fedId]; if (frs.readoutTypes_.empty()) { continue; } @@ -121,7 +121,7 @@ void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) else { oneapi::tbb::this_task_arena::isolate([&]() { oneapi::tbb::parallel_for(0U, moduleIndexer.fedCount(), [&](unsigned fedId) { - const auto& frs = moduleIndexer.getFEDReadoutSequences()[fedId]; + const auto& frs = moduleIndexer.fedReadoutSequences()[fedId]; if (frs.readoutTypes_.empty()) { return; } diff --git a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc index 352c5e726f405..2295e1545cf5e 100644 --- a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc +++ b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc @@ -28,7 +28,7 @@ uint16_t HGCalUnpacker::parseFEDData(unsigned fedId, hgcaldigi::HGCalECONDPacketInfoHost& econdPacketInfo, bool headerOnlyMode) { // ReadoutSequence object for this FED - const auto& fedReadoutSequence = moduleIndexer.getFEDReadoutSequences()[fedId]; + const auto& fedReadoutSequence = moduleIndexer.fedReadoutSequences()[fedId]; // Configuration object for this FED const auto& fedConfig = config.feds[fedId]; @@ -266,7 +266,7 @@ uint16_t HGCalUnpacker::parseFEDData(unsigned fedId, // parse ECON-D body(eRx subpackets) const auto enabledErx = fedReadoutSequence.enabledErx_[globalECONDIdx]; - const auto erxMax = moduleIndexer.getGlobalTypesNErx()[fedReadoutSequence.readoutTypes_[globalECONDIdx]]; + const auto erxMax = moduleIndexer.globalTypesNErx()[fedReadoutSequence.readoutTypes_[globalECONDIdx]]; const bool pass_through_mode = (econd_headers[0] >> ECOND_FRAME::BITP_POS) & 0b1; unsigned iword = 0; diff --git a/Geometry/HGCalMapping/interface/HGCalMappingTools.h b/Geometry/HGCalMapping/interface/HGCalMappingTools.h index f479406105e59..be08f50df252b 100644 --- a/Geometry/HGCalMapping/interface/HGCalMappingTools.h +++ b/Geometry/HGCalMapping/interface/HGCalMappingTools.h @@ -31,18 +31,21 @@ namespace hgcal { /** * @short gets the attribute corresponding the column col in a row */ - HGCalEntityAttr getAttr(std::string col, HGCalEntityRow &row) { + const HGCalEntityAttr &getAttr(const std::string &col, const HGCalEntityRow &row) const { auto it = columnIndex_.find(col); if (it == columnIndex_.end()) { throw cms::Exception("ValueError") << "Request for unknown column " << col; } - return row[it->second]; + return row.at(it->second); //[it->second]; } - float getFloatAttr(std::string col, HGCalEntityRow &row) { return (float)atof(getAttr(col, row).c_str()); } - float getIntAttr(std::string col, HGCalEntityRow &row) { return atoi(getAttr(col, row).c_str()); } - const std::vector &getEntries() { return entities_; } - HGCalEntityRow getColumnNames() { return colNames_; } - bool hasColumn(std::string_view col) { + + float getFloatAttr(std::string col, const HGCalEntityRow &row) const { + return (float)atof(getAttr(col, row).c_str()); + } + float getIntAttr(std::string col, const HGCalEntityRow &row) const { return atoi(getAttr(col, row).c_str()); } + const std::vector &getEntries() const { return entities_; } + const HGCalEntityRow &getColumnNames() const { return colNames_; } + bool hasColumn(std::string_view col) const { return std::find(colNames_.begin(), colNames_.end(), col) != colNames_.end(); } diff --git a/Geometry/HGCalMapping/plugins/BuildFile.xml b/Geometry/HGCalMapping/plugins/BuildFile.xml index 694c9c89548a8..f5f6a7a4e8ffa 100644 --- a/Geometry/HGCalMapping/plugins/BuildFile.xml +++ b/Geometry/HGCalMapping/plugins/BuildFile.xml @@ -13,6 +13,10 @@ + + + + diff --git a/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc b/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc index c9d0bf0984a68..5212adb4d9525 100644 --- a/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc +++ b/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc @@ -24,12 +24,9 @@ class HGCalMappingESProducer : public edm::ESProducer, public edm::EventSetupRec public: explicit HGCalMappingESProducer(const edm::ParameterSet& iConfig) { //parse the files and hold the list of entities in memory - for (auto v : {"modules", "si", "sipm"}) { - edm::FileInPath fip = iConfig.getParameter(v); - hgcal::mappingtools::HGCalEntityList pmap; - pmap.buildFrom(fip.fullPath()); - parsedMaps_[v] = pmap; - } + modulesMap_.buildFrom(iConfig.getParameter("modules").fullPath()); + sicellsMap_.buildFrom(iConfig.getParameter("si").fullPath()); + sipmCellsMap_.buildFrom(iConfig.getParameter("sipm").fullPath()); setWhatProduced(this, &HGCalMappingESProducer::produceCellMapIndexer); setWhatProduced(this, &HGCalMappingESProducer::produceModuleMapIndexer); @@ -67,18 +64,18 @@ class HGCalMappingESProducer : public edm::ESProducer, public edm::EventSetupRec void prepareCellMapperIndexer(); void prepareModuleMapperIndexer(); - std::map parsedMaps_; + hgcal::mappingtools::HGCalEntityList modulesMap_, sicellsMap_, sipmCellsMap_; HGCalMappingCellIndexer cellIndexer_; HGCalMappingModuleIndexer modIndexer_; }; // void HGCalMappingESProducer::prepareCellMapperIndexer() { - for (auto v : {"si", "sipm"}) { - auto& pmap = parsedMaps_[v]; + for (size_t i = 0; i < 2; i++) { + const auto& pmap = i == 0 ? sicellsMap_ : sipmCellsMap_; const auto& entities = pmap.getEntries(); - for (auto row : entities) { - std::string typecode = pmap.getAttr("Typecode", row); + for (const auto& row : entities) { + const std::string& typecode = pmap.getAttr("Typecode", row); int chip = pmap.getIntAttr("ROC", row); int half = pmap.getIntAttr("HalfROC", row); cellIndexer_.processNewCell(typecode, chip, half); @@ -100,11 +97,10 @@ void HGCalMappingESProducer::prepareModuleMapperIndexer() { auto defaultTypeNWords = cellIndexer_.getNWordsExpectedFor(defaultTypeCodeIdx); auto nwords = defaultTypeNWords; - auto& pmap = parsedMaps_["modules"]; - auto& entities = pmap.getEntries(); - for (auto row : entities) { - std::string typecode = pmap.getAttr("typecode", row); // module type code - std::string wtypecode; // wafer type code + const auto& entities = modulesMap_.getEntries(); + for (const auto& row : entities) { + const std::string& typecode = modulesMap_.getAttr("typecode", row); // module type code + std::string wtypecode; // wafer type code // match module type code to regular expression pattern (MM-TTTT-LL-NNNN) // see https://edms.cern.ch/ui/#!master/navigator/document?D:101059405:101148061:subDocs @@ -126,26 +122,13 @@ void HGCalMappingESProducer::prepareModuleMapperIndexer() { } } - try { - typecodeidx = cellIndexer_.getEnumFromTypecode(wtypecode); - nwords = cellIndexer_.getNWordsExpectedFor(wtypecode); - nerx = cellIndexer_.getNErxExpectedFor(wtypecode); - } catch (cms::Exception& e) { - int plane = pmap.getIntAttr("plane", row); - int u = pmap.getIntAttr("u", row); - int v = pmap.getIntAttr("v", row); - edm::LogWarning("HGCalMappingESProducer") << "Exception caught decoding index for typecode=" << typecode - << " @ plane=" << plane << " u=" << u << " v=" << v << "\n" - << e.what() << "\n" - << "===> will assign default (MH-F) which may be inefficient"; - typecodeidx = defaultTypeCodeIdx; - nwords = defaultTypeNWords; - nerx = defaultNerx; - } + typecodeidx = cellIndexer_.getEnumFromTypecode(wtypecode); + nwords = cellIndexer_.getNWordsExpectedFor(wtypecode); + nerx = cellIndexer_.getNErxExpectedFor(wtypecode); - int fedid = pmap.getIntAttr("fedid", row); - int captureblockidx = pmap.getIntAttr("captureblockidx", row); - int econdidx = pmap.getIntAttr("econdidx", row); + int fedid = modulesMap_.getIntAttr("fedid", row); + int captureblockidx = modulesMap_.getIntAttr("captureblockidx", row); + int econdidx = modulesMap_.getIntAttr("econdidx", row); modIndexer_.processNewModule(fedid, captureblockidx, econdidx, typecodeidx, nerx, nwords, typecode); } diff --git a/Geometry/HGCalMapping/plugins/HGCalMappingTriggerESProducer.cc b/Geometry/HGCalMapping/plugins/HGCalMappingTriggerESProducer.cc new file mode 100644 index 0000000000000..fc32a632763c8 --- /dev/null +++ b/Geometry/HGCalMapping/plugins/HGCalMappingTriggerESProducer.cc @@ -0,0 +1,140 @@ +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/SourceFactory.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ESProducts.h" +#include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/do_nothing_deleter.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" + +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" + +#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" +#include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" +#include // regular expression + +/** + @short plugin parses the module/cell locator files to produce the indexer records + */ +class HGCalMappingTriggerESProducer : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder { +public: + explicit HGCalMappingTriggerESProducer(const edm::ParameterSet& iConfig) { + //parse the files and hold the list of entities in memory + modulesMap_.buildFrom(iConfig.getParameter("modules").fullPath()); + sicellsMap_.buildFrom(iConfig.getParameter("si").fullPath()); + sipmCellsMap_.buildFrom(iConfig.getParameter("sipm").fullPath()); + + setWhatProduced(this, &HGCalMappingTriggerESProducer::produceCellMapIndexer); + setWhatProduced(this, &HGCalMappingTriggerESProducer::produceModuleMapIndexer); + + findingRecord(); + + prepareCellMapperIndexer(); + prepareModuleMapperIndexer(); + } + + std::shared_ptr produceModuleMapIndexer(const HGCalElectronicsMappingRcd&) { + return std::shared_ptr(&modIndexer_, edm::do_nothing_deleter()); + } + + std::shared_ptr produceCellMapIndexer(const HGCalElectronicsMappingRcd&) { + return std::shared_ptr(&cellIndexer_, edm::do_nothing_deleter()); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("modules")->setComment("module locator file"); + desc.add("si")->setComment("file containing the mapping of the readout cells in Si modules"); + desc.add("sipm")->setComment( + "file containing the mapping of the readout cells in SiPM-on-tile modules"); + descriptions.addWithDefaultLabel(desc); + } + +private: + void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&, + const edm::IOVSyncValue&, + edm::ValidityInterval& oValidity) override { + oValidity = edm::ValidityInterval(edm::IOVSyncValue::beginOfTime(), edm::IOVSyncValue::endOfTime()); + } + + void prepareCellMapperIndexer(); + void prepareModuleMapperIndexer(); + + hgcal::mappingtools::HGCalEntityList modulesMap_, sicellsMap_, sipmCellsMap_; + HGCalMappingCellIndexerTrigger cellIndexer_; + HGCalMappingModuleIndexerTrigger modIndexer_; +}; + +// +void HGCalMappingTriggerESProducer::prepareCellMapperIndexer() { + for (size_t i = 0; i < 2; i++) { + const auto& pmap = i == 0 ? sicellsMap_ : sipmCellsMap_; + const auto& entities = pmap.getEntries(); + for (const auto& row : entities) { + auto typecode = pmap.getAttr("Typecode", row); + int ROC = pmap.getIntAttr("ROC", row); + int trLink = pmap.getIntAttr("TrLink", row); + int trCell = pmap.getIntAttr("TrCell", row); + cellIndexer_.processNewCell(typecode, ROC, trLink, trCell); + } + } + + // all {hex,tile}board types are loaded finalize the mapping indexer + cellIndexer_.update(); +} + +// +void HGCalMappingTriggerESProducer::prepareModuleMapperIndexer() { + //default values to assign in case module type has not yet been mapped + //a high density module (max possible) will be assigned so that the mapping doesn't block + auto defaultTypeCodeIdx = cellIndexer_.getEnumFromTypecode("MH-F"); + auto typecodeidx = defaultTypeCodeIdx; + auto defaultNTrLinks = cellIndexer_.getNTrLinkExpectedFor(defaultTypeCodeIdx); + auto nTrLinks = defaultNTrLinks; + auto defaultTypeNTCs = cellIndexer_.getNWordsExpectedFor(defaultTypeCodeIdx); + auto nwords = defaultTypeNTCs; + + const auto& entities = modulesMap_.getEntries(); + for (const auto& row : entities) { + auto typecode = modulesMap_.getAttr("typecode", row); // module type code + std::string wtypecode; // wafer type code + + // match module type code to regular expression pattern (MM-TTTT-LL-NNNN) + // see https://edms.cern.ch/ui/#!master/navigator/document?D:101059405:101148061:subDocs + const std::regex typecode_regex_si("(([MX])([LH])-([FTBLR5])).*"); // MM-T* + + // match typecode to regular expression SiPM (TX-LYYSZ-NNNN) + // https://indico.cern.ch/event/1558202/contributions/6567912/attachments/3092451/5477467/hgcalweek_DPG_2025.pdf : slide 8 + const std::regex typecode_regex_sipm("(T[HL]-L[0-9]+S[123]).*"); // SiPM typecode format TM- + std::smatch typecode_match_si, typecode_match_sipm; // match object for string objects + + bool matched_si = std::regex_match(typecode, typecode_match_si, typecode_regex_si); + bool matched_sipm = std::regex_match(typecode, typecode_match_sipm, typecode_regex_sipm); + if (matched_si) { + wtypecode = typecode_match_si[1].str(); // wafer type following MM-T pattern, e.g. "MH-F" + } else if (matched_sipm) { + wtypecode = typecode_match_sipm[1].str(); + } else { + edm::LogWarning("HGCalMappingIndexESSource") + << "Could not match module type code to expected pattern: " << typecode; + } + + typecodeidx = cellIndexer_.getEnumFromTypecode(wtypecode); + nTrLinks = cellIndexer_.getNTrLinkExpectedFor(wtypecode); + nwords = cellIndexer_.getNWordsExpectedFor(wtypecode); + + int fedid = modulesMap_.getIntAttr("trig_fedid", row); + int econtidx = modulesMap_.getIntAttr("econtidx", row); + modIndexer_.processNewModule(fedid, econtidx, typecodeidx, nTrLinks, nwords, typecode); + } + + modIndexer_.finalize(); +} + +DEFINE_FWK_EVENTSETUP_SOURCE(HGCalMappingTriggerESProducer); diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc index 9a48ed73cbec1..4a5f24cf65f62 100644 --- a/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc @@ -67,14 +67,14 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { //declare the dense index info collection to be produced //the size is determined by the module indexer - const uint32_t nIndices = modIndexer.getMaxDataSize(); + const uint32_t nIndices = modIndexer.maxDataSize(); HGCalDenseIndexInfoHost denseIdxInfo(nIndices, cms::alpakatools::host()); - for (auto fedRS : modIndexer.getFEDReadoutSequences()) { + for (auto fedRS : modIndexer.fedReadoutSequences()) { uint32_t fedId = fedRS.id; for (size_t imod = 0; imod < fedRS.readoutTypes_.size(); imod++) { //the number of words expected, the first channel dense index int modTypeIdx = fedRS.readoutTypes_[imod]; - uint32_t nch = modIndexer.getGlobalTypesNWords()[modTypeIdx]; + uint32_t nch = modIndexer.globalTypesNWords()[modTypeIdx]; int off = fedRS.chDataOffsets_[imod]; //get additional necessary module info diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexTriggerInfoESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexTriggerInfoESProducer.cc new file mode 100644 index 0000000000000..21c97e883ad14 --- /dev/null +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexTriggerInfoESProducer.cc @@ -0,0 +1,141 @@ +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ModuleFactory.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" +#include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" + +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h" + +#include +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcal { + + class HGCalDenseIndexTriggerInfoESProducer : public ESProducer { + public: + // + HGCalDenseIndexTriggerInfoESProducer(const edm::ParameterSet& iConfig) : ESProducer(iConfig) { + auto cc = setWhatProduced(this); + moduleIndexTkn_ = cc.consumes(iConfig.getParameter("moduleindexer")); + cellIndexTkn_ = cc.consumes(iConfig.getParameter("cellindexer")); + moduleInfoTkn_ = cc.consumes(iConfig.getParameter("moduleinfo")); + cellInfoTkn_ = cc.consumes(iConfig.getParameter("cellinfo")); + } + + // + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("moduleindexer", edm::ESInputTag(""))->setComment("Module index tool"); + desc.add("cellindexer", edm::ESInputTag(""))->setComment("Dense cell index tool"); + desc.add("moduleinfo", edm::ESInputTag(""))->setComment("Module info table"); + desc.add("cellinfo", edm::ESInputTag(""))->setComment("Cell info table"); + descriptions.addWithDefaultLabel(desc); + } + + // + std::optional produce(const HGCalDenseIndexInfoRcd& iRecord) { + //get cell and module indexer + auto const& modIndexer = iRecord.get(moduleIndexTkn_); + auto const& cellIndexer = iRecord.get(cellIndexTkn_); + + //get cell and module info + auto const& moduleInfo = iRecord.get(moduleInfoTkn_); + auto const& cellInfo = iRecord.get(cellInfoTkn_); + + //declare the dense index info collection to be produced + //the size is determined by the module indexer + const uint32_t nIndices = modIndexer.maxDataSize(); + HGCalDenseIndexTriggerInfoHost denseIdxInfo(nIndices, cms::alpakatools::host()); + for (const auto& fedRS : modIndexer.fedReadoutSequences()) { + uint32_t fedId = fedRS.id; + for (size_t imod = 0; imod < fedRS.readoutTypes_.size(); imod++) { + //the number of words expected, the first channel dense index + int modTypeIdx = fedRS.readoutTypes_[imod]; + uint32_t nch = modIndexer.globalTypesNTCs()[modTypeIdx]; + int off = fedRS.TCOffsets_[imod]; + + //get additional necessary module info + int modIdx = modIndexer.getIndexForModule(fedId, static_cast(imod)); + const auto& module_row = moduleInfo.view()[modIdx]; + bool isSiPM = module_row.isSiPM(); + uint16_t typeidx = module_row.typeidx(); + uint32_t muxid = module_row.muxid(); + + //get the offset to start reading the cell info from sequential + uint32_t cellInfoOffset = cellIndexer.offsets_[typeidx]; + + //now fill the information sequentially on the cells of this module + for (uint32_t ich = 0; ich < nch; ich++) { + //finalize assigning the dense index + uint32_t denseIdx = off + ich; + + auto row = denseIdxInfo.view()[denseIdx]; + + //fill the fields + row.fedId() = fedId; + row.fedReadoutSeq() = imod; + row.TCNumber() = ich; + row.modInfoIdx() = modIdx; + uint32_t cellIdx = cellInfoOffset + ich; + row.cellInfoIdx() = cellIdx; + + const auto& cell_row = cellInfo.view()[cellIdx]; + row.muxid() = muxid + ich; + + //assign det id only for full and calibration cells + row.trigdetid() = 0; + if (cell_row.t() == 1 || cell_row.t() == 0) { + if (isSiPM) { + row.trigdetid() = ::hgcal::mappingtools::getSiPMDetId(module_row.zside(), + module_row.plane(), + module_row.i2(), + module_row.celltype(), + cell_row.i1(), + cell_row.i2()); + } else { + row.trigdetid() = module_row.trigdetid() + cell_row.detid(); + } + + //TODO: assign position from geometry, for the moment no position is assigned + row.x() = 0; + row.y() = 0; + row.z() = 0; + } + } // end cell loop + + } // end module loop + + } // end fed readout sequence loop + + return denseIdxInfo; + } // end of produce() + + private: + edm::ESGetToken moduleIndexTkn_; + edm::ESGetToken cellIndexTkn_; + edm::ESGetToken moduleInfoTkn_; + edm::ESGetToken cellInfoTkn_; + }; + + } // namespace hgcal + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(hgcal::HGCalDenseIndexTriggerInfoESProducer); diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc index b883efa8d6b3e..f1e0a995f8ad4 100644 --- a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc @@ -63,11 +63,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { ::hgcal::mappingtools::HGCalEntityList omap; edm::FileInPath fip(offsetfile); omap.buildFrom(fip.fullPath()); - auto& mapEntries = omap.getEntries(); - for (auto row : mapEntries) { + const auto& mapEntries = omap.getEntries(); + for (const auto& row : mapEntries) { std::string typecode = omap.getAttr("Typecode", row); - const auto& allTypecodes = moduleIndexer.getTypecodeMap(); + const auto& allTypecodes = moduleIndexer.typecodeMap(); // Skip if typecode is not in the module indexer bool typecodeFound = false; for (const auto& key : allTypecodes) { @@ -105,10 +105,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { ::hgcal::mappingtools::HGCalEntityList pmap; edm::FileInPath fip(url); pmap.buildFrom(fip.fullPath()); - auto& entities = pmap.getEntries(); - for (auto row : entities) { + const auto& entities = pmap.getEntries(); + for (const auto& row : entities) { //identify special cases (Si vs SiPM, calib vs normal) - std::string typecode = pmap.getAttr("Typecode", row); + const std::string& typecode = pmap.getAttr("Typecode", row); auto typeidx = cellIndexer.getEnumFromTypecode(typecode); bool isSiPM = (typecode[0] == 'T'); int rocpin = pmap.getIntAttr("ROCpin", row); diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc index e854488099b30..7458e3fffc6fb 100644 --- a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc @@ -55,14 +55,15 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { ::hgcal::mappingtools::HGCalEntityList pmap; pmap.buildFrom(filename_.fullPath()); - auto& entities = pmap.getEntries(); - for (auto row : entities) { + const auto& entities = pmap.getEntries(); + for (const auto& row : entities) { + int cassette = pmap.hasColumn("cassette") ? pmap.getIntAttr("cassette", row) : 1; int fedid = pmap.getIntAttr("fedid", row); int captureblockidx = pmap.getIntAttr("captureblockidx", row); int econdidx = pmap.getIntAttr("econdidx", row); int idx = modIndexer.getIndexForModule(fedid, captureblockidx, econdidx); int typeidx = modIndexer.getTypeForModule(fedid, captureblockidx, econdidx); - std::string typecode = pmap.getAttr("typecode", row); + const std::string& typecode = pmap.getAttr("typecode", row); auto celltypes = modIndexer.getCellType(typecode); bool isSiPM = celltypes.first; @@ -74,7 +75,6 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { uint8_t irot = (uint8_t)(pmap.hasColumn("irot") ? pmap.getIntAttr("irot", row) : 0); uint32_t eleid = HGCalElectronicsId((zside > 0), fedid, captureblockidx, econdidx, 0, 0).raw(); uint32_t detid(0); - if (!isSiPM) { int zp(zside > 0 ? 1 : -1); DetId::Detector det = plane <= 26 ? DetId::Detector::HGCalEE : DetId::Detector::HGCalHSi; @@ -98,6 +98,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { module.captureblockidx() = captureblockidx; module.eleid() = eleid; module.detid() = detid; + module.cassette() = cassette; } return moduleParams; diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingTriggerModuleESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingTriggerModuleESProducer.cc new file mode 100644 index 0000000000000..ea1df598789f7 --- /dev/null +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingTriggerModuleESProducer.cc @@ -0,0 +1,116 @@ +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ModuleFactory.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCalTriggerDetId.h" +#include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" + +#include +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcal { + + class HGCalMappingTriggerModuleESProducer : public ESProducer { + public: + // + HGCalMappingTriggerModuleESProducer(const edm::ParameterSet& iConfig) + : ESProducer(iConfig), filename_(iConfig.getParameter("filename")) { + auto cc = setWhatProduced(this); + moduleIndexTriggerTkn_ = cc.consumes(iConfig.getParameter("moduleindexer")); + } + + // + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("filename")->setComment("module locator file"); + desc.add("moduleindexer", edm::ESInputTag(""))->setComment("Dense module index tool"); + descriptions.addWithDefaultLabel(desc); + } + + // + std::optional produce(const HGCalElectronicsMappingRcd& iRecord) { + //get cell and module indexer + const auto& modIndexer = iRecord.get(moduleIndexTriggerTkn_); + + // load dense indexing + const uint32_t size = modIndexer.maxModulesIndex(); + HGCalMappingModuleTriggerParamHost moduleParams(size, cms::alpakatools::host()); + for (size_t i = 0; i < size; i++) + moduleParams.view()[i].valid() = false; + + ::hgcal::mappingtools::HGCalEntityList pmap; + pmap.buildFrom(filename_.fullPath()); + const auto& entities = pmap.getEntries(); + for (const auto& row : entities) { + int cassette = pmap.hasColumn("cassette") ? pmap.getIntAttr("cassette", row) : 1; + int fedid = pmap.getIntAttr("trig_fedid", row); + int econtidx = pmap.getIntAttr("econtidx", row); + int idx = modIndexer.getIndexForModule(fedid, static_cast(econtidx)); + int typeidx = modIndexer.getTypeForModule(fedid, static_cast(econtidx)); + const std::string& typecode = pmap.getAttr("typecode", row); + + auto celltypes = modIndexer.getCellType(typecode); + bool isSiPM = celltypes.first; + int celltype = celltypes.second; + int zside = pmap.getIntAttr("zside", row); + int plane = pmap.getIntAttr("plane", row); + int i1 = pmap.getIntAttr("u", row); + int i2 = pmap.getIntAttr("v", row); + uint8_t irot = (uint8_t)(pmap.hasColumn("irot") ? pmap.getIntAttr("irot", row) : 0); + // TODO : muxid needs to be discussed with BE and will be assigned correctly in the next iteration + uint32_t muxid(0); + uint32_t trigdetid(0); + if (!isSiPM) { + int zp(zside > 0 ? 1 : -1); + int subdet = ForwardSubdetector::ForwardEmpty; + trigdetid = HGCalTriggerDetId(subdet, zp, celltype, plane, i1, i2, 0, 0).rawId(); + } + + auto module = moduleParams.view()[idx]; + module.valid() = true; + module.zside() = (zside > 0); + module.isSiPM() = isSiPM; + module.plane() = plane; + module.i1() = i1; + module.i2() = i2; + module.irot() = irot; + module.celltype() = celltype; + module.typeidx() = typeidx; + module.fedid() = fedid; + module.slinkidx() = pmap.getIntAttr("slinkidx", row); + module.econtidx() = econtidx; + module.muxid() = muxid; + module.trigdetid() = trigdetid; + module.cassette() = cassette; + } + + return moduleParams; + + } // end of produce() + + private: + edm::ESGetToken moduleIndexTriggerTkn_; + const edm::FileInPath filename_; + }; + + } // namespace hgcal + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(hgcal::HGCalMappingTriggerModuleESProducer); diff --git a/Geometry/HGCalMapping/python/hgcalmapping_cff.py b/Geometry/HGCalMapping/python/hgcalmapping_cff.py index bbd69fb8326c8..acc4d8c956ef9 100644 --- a/Geometry/HGCalMapping/python/hgcalmapping_cff.py +++ b/Geometry/HGCalMapping/python/hgcalmapping_cff.py @@ -4,7 +4,8 @@ def customise_hgcalmapper(process, modules = 'Geometry/HGCalMapping/data/ModuleMaps/modulelocator_test.txt', sicells = 'Geometry/HGCalMapping/data/CellMaps/WaferCellMapTraces.txt', sipmcells = 'Geometry/HGCalMapping/data/CellMaps/channels_sipmontile.hgcal.txt', - offsetfile = 'Geometry/HGCalMapping/data/CellMaps/calibration_to_surrounding_offsetMap.txt'): + offsetfile = 'Geometry/HGCalMapping/data/CellMaps/calibration_to_surrounding_offsetMap.txt', + trigmodule = 'Geometry/HGCalMapping/data/ModuleMaps/modulelocator_trigger_test.txt'): """the following function configures the mapping producers NOTE: for production-targetted configs should be avoided as it checks if the process as already the Accelerators sequence loaded, if not it loads it to the process""" @@ -14,6 +15,11 @@ def customise_hgcalmapper(process, process.hgCalMappingESProducer.si = cms.FileInPath(sicells) process.hgCalMappingESProducer.sipm = cms.FileInPath(sipmcells) + process.load('Geometry.HGCalMapping.hgCalMappingTriggerESProducer_cfi') + process.hgCalMappingTriggerESProducer.modules = cms.FileInPath(trigmodule) + process.hgCalMappingTriggerESProducer.si = cms.FileInPath(sicells) + process.hgCalMappingTriggerESProducer.sipm = cms.FileInPath(sipmcells) + if not hasattr(process, 'ProcessAcceleratorCUDA'): process.load('Configuration.StandardSequences.Accelerators_cff') @@ -26,5 +32,11 @@ def customise_hgcalmapper(process, moduleindexer=cms.ESInputTag('')) process.hgCalDenseIndexInfoESProducer = cms.ESProducer('hgcal::HGCalDenseIndexInfoESProducer@alpaka', moduleindexer=cms.ESInputTag('') ) - + + process.hgCalMappingModuleTriggerESProducer = cms.ESProducer('hgcal::HGCalMappingTriggerModuleESProducer@alpaka', + filename=cms.FileInPath(trigmodule), + moduleindexer=cms.ESInputTag('')) + process.hgCalDenseIndexTriggerInfoESProducer = cms.ESProducer('hgcal::HGCalDenseIndexTriggerInfoESProducer@alpaka', + moduleindexer=cms.ESInputTag('') ) + return process diff --git a/Geometry/HGCalMapping/test/BuildFile.xml b/Geometry/HGCalMapping/test/BuildFile.xml index 3420551934e71..0b1e45673ddf5 100644 --- a/Geometry/HGCalMapping/test/BuildFile.xml +++ b/Geometry/HGCalMapping/test/BuildFile.xml @@ -4,7 +4,7 @@ - + diff --git a/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc b/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc index bb9b76451ca53..43f03db02df75 100644 --- a/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc +++ b/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc @@ -90,7 +90,7 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev typecode.c_str(), idx, cellIdx.maxErx_[idx], - cellIdx.di_[idx].getMaxIndex(), + cellIdx.di_[idx].maxIndex(), cellIdx.offsets_[idx]); } @@ -134,12 +134,12 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev auto const& modulesIdx = iSetup.getData(moduleIndexTkn_); printf("[HGCalMappingIndexESSourceTester][analyze] Module indexer has FEDs=%d Types in sequences=%ld max idx=%d\n", modulesIdx.fedCount(), - modulesIdx.getGlobalTypesCounter().size(), + modulesIdx.globalTypesCounter().size(), modulesIdx.maxModulesIndex()); printf("[HGCalMappingIndexESSourceTester][analyze] FED Readout sequence\n"); std::unordered_set unique_modOffsets, unique_erxOffsets, unique_chDataOffsets; uint32_t totalmods(0); - for (const auto& frs : modulesIdx.getFEDReadoutSequences()) { + for (const auto& frs : modulesIdx.fedReadoutSequences()) { std::copy( frs.modOffsets_.begin(), frs.modOffsets_.end(), std::inserter(unique_modOffsets, unique_modOffsets.end())); std::copy( @@ -178,7 +178,7 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev validModules++; printf( "\t idx=%d zside=%d isSiPM=%d plane=%d i1=%d i2=%d irot=%d celltype=%d typeidx=%d fedid=%d localfedid=%d " - "captureblock=%d capturesblockidx=%d econdidx=%d eleid=0x%x detid=0x%d\n", + "captureblock=%d capturesblockidx=%d econdidx=%d eleid=0x%x detid=0x%d cassette=0x%d\n", i, imod.zside(), imod.isSiPM(), @@ -194,7 +194,8 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev imod.captureblockidx(), imod.econdidx(), imod.eleid(), - imod.detid()); + imod.detid(), + imod.cassette()); } printf( diff --git a/Geometry/HGCalMapping/test/HGCalMappingTriggerESSourceTester.cc b/Geometry/HGCalMapping/test/HGCalMappingTriggerESSourceTester.cc new file mode 100644 index 0000000000000..0dc24574e388b --- /dev/null +++ b/Geometry/HGCalMapping/test/HGCalMappingTriggerESSourceTester.cc @@ -0,0 +1,352 @@ +#include +#include +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "FWCore/Framework/interface/ESWatcher.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" + +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexerTrigger.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" +#include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" + +class HGCalMappingTriggerESSourceTester : public edm::one::EDAnalyzer<> { +public: + explicit HGCalMappingTriggerESSourceTester(const edm::ParameterSet&); + static void fillDescriptions(edm::ConfigurationDescriptions&); + std::map mapGeoToElectronics(const hgcal::HGCalMappingModuleTriggerParamHost& modules, + const hgcal::HGCalMappingCellParamHost& cells, + bool geo2ele, + bool sipm); + +private: + void analyze(const edm::Event&, const edm::EventSetup&) override; + + edm::ESWatcher cfgWatcher_; + edm::ESGetToken cellIndexTkn_; + edm::ESGetToken cellTkn_; + edm::ESGetToken moduleIndexTkn_; + edm::ESGetToken moduleTkn_; + edm::ESGetToken denseIndexTkn_; +}; + +// +HGCalMappingTriggerESSourceTester::HGCalMappingTriggerESSourceTester(const edm::ParameterSet& iConfig) + : cellIndexTkn_(esConsumes()), + cellTkn_(esConsumes()), + moduleIndexTkn_(esConsumes()), + moduleTkn_(esConsumes()), + denseIndexTkn_(esConsumes()) {} + +// +void HGCalMappingTriggerESSourceTester::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + // if the cfg didn't change there's nothing else to do + if (!cfgWatcher_.check(iSetup)) + return; + + //get cell indexers and SoA + auto const& cellIdx = iSetup.getData(cellIndexTkn_); + auto const& cells = iSetup.getData(cellTkn_); + printf("[HGCalMappingIndexESSourceTester][analyze] Cell dense indexers and associated SoA retrieved for HGCAL\n"); + int nmodtypes = cellIdx.typeCodeIndexer_.size(); + printf("[HGCalMappingIndexESSourceTester][analyze] module cell indexer has %d module types\n", nmodtypes); + + //printout and test the indexer contents for cells + printf("[HGCalMappingIndexESSourceTester][analyze] Test indexer\n"); + uint32_t totOffset(0); + for (size_t idx = 0; idx < cellIdx.di_.size(); idx++) { + //check typecode exists + const auto& typecode = cellIdx.getTypecodeFromEnum(idx); + assert(cellIdx.typeCodeIndexer_.count(typecode) == 1); + + //check that the current offset is consistent with the increment from cells from the previous module + if (idx > 0) { + uint32_t nch_prev = cellIdx.maxROC_[idx - 1] * cellIdx.maxTrLink_[idx - 1] * cellIdx.maxTCPerLink_[idx - 1]; + uint32_t delta_offset = cellIdx.offsets_[idx] - cellIdx.offsets_[idx - 1]; + assert(delta_offset == nch_prev); + } + + //assert offset is consistent with the accumulation + uint32_t off = cellIdx.offsets_[idx]; + assert(off == totOffset); + + totOffset += cellIdx.maxROC_[idx] * cellIdx.maxTrLink_[idx] * cellIdx.maxTCPerLink_[idx]; + + //print + printf( + "[HGCalMappingIndexESSourceTester][analyze][%s] has index(internal)=%ld #ROCs=%d #TLinks=%d #TCells=%d " + "offset=%d-%d\n", + typecode.c_str(), + idx, + cellIdx.maxROC_[idx], + cellIdx.maxTrLink_[idx], + cellIdx.di_[idx].maxIndex(), + cellIdx.offsets_[idx], + totOffset); + } + assert(totOffset == cellIdx.maxDenseIndex()); + printf("[HGCalMappingIndexESSourceTester][analyze] SoA size for module cell mapping will be %d\n", totOffset); + + //printout and test module cells SoA contents + uint32_t ncells = cells.view().metadata().size(); + uint32_t validCells = 0; + printf("[HGCalMappingIndexESSourceTester][analyze] Module cell mapping contents\n"); + for (uint32_t i = 0; i < ncells; i++) { + auto icell = cells.view()[i]; + if (!cells.view()[i].valid()) + continue; + validCells++; + printf( + "\t idx=%d isHD=%d iscalib=%d isSiPM=%d typeidx=%d chip=%d half=%d seq=%d rocpin=%d sensorcell=%d triglink=%d " + "trigcell=%d i1=%d i2=%d t=%d trace=%f eleid=0x%x detid=0x%x\n", + i, + icell.isHD(), + icell.iscalib(), + icell.isSiPM(), + icell.typeidx(), + icell.chip(), + icell.half(), + icell.seq(), + icell.rocpin(), + icell.sensorcell(), + icell.triglink(), + icell.trigcell(), + icell.i1(), + icell.i2(), + icell.t(), + icell.trace(), + icell.eleid(), + icell.detid()); + } + + //module mapping + auto const& modulesIdx = iSetup.getData(moduleIndexTkn_); + printf("[HGCalMappingIndexESSourceTester][analyze] Module indexer has FEDs=%d Types in sequences=%ld max idx=%d\n", + modulesIdx.fedCount(), + modulesIdx.globalTypesCounter().size(), + modulesIdx.maxModulesIndex()); + printf("[HGCalMappingIndexESSourceTester][analyze] FED Readout sequence\n"); + std::unordered_set unique_modOffsets, unique_TrLinkOffsets, unique_TCOffsets; + uint32_t totalmods(0); + for (const auto& frs : modulesIdx.fedReadoutSequences()) { + std::copy( + frs.modOffsets_.begin(), frs.modOffsets_.end(), std::inserter(unique_modOffsets, unique_modOffsets.end())); + std::copy(frs.TrLinkOffsets_.begin(), + frs.TrLinkOffsets_.end(), + std::inserter(unique_TrLinkOffsets, unique_TrLinkOffsets.end())); + std::copy(frs.TCOffsets_.begin(), frs.TCOffsets_.end(), std::inserter(unique_TCOffsets, unique_TCOffsets.end())); + + size_t nmods = frs.readoutTypes_.size(); + totalmods += nmods; + printf("\t[FED %d] packs data from %ld ECON-Ts - readout types -> (offsets) :", frs.id, nmods); + for (size_t i = 0; i < nmods; i++) { + printf("\t%d -> (%d;%d;%d)", frs.readoutTypes_[i], frs.modOffsets_[i], frs.TrLinkOffsets_[i], frs.TCOffsets_[i]); + } + printf("\n"); + } + //check that there are unique offsets per modules in the full system + assert(unique_modOffsets.size() == totalmods); + assert(unique_TrLinkOffsets.size() == totalmods); + assert(unique_TCOffsets.size() == totalmods); + + //get the module mapper SoA + auto const& modules = iSetup.getData(moduleTkn_); + int nmodules = modulesIdx.maxModulesIndex(); + int validModules = 0; + assert(nmodules == modules.view().metadata().size()); //check for consistent size + printf("[HGCalMappingIndexESSourceTester][analyze] Module mapping contents\n"); + for (int i = 0; i < nmodules; i++) { + auto imod = modules.view()[i]; + if (!modules.view()[i].valid()) + continue; + validModules++; + printf( + "\t idx=%d zside=%d isSiPM=%d plane=%d i1=%d i2=%d irot=%d celltype=%d typeidx=%d fedid=%d localfedid=%d " + "econtidx=%d muxid=0x%x trigid=0x%d cassette=0x%d\n", + i, + imod.zside(), + imod.isSiPM(), + imod.plane(), + imod.i1(), + imod.i2(), + imod.irot(), + imod.celltype(), + imod.typeidx(), + imod.fedid(), + imod.slinkidx(), + imod.econtidx(), + imod.muxid(), + imod.trigdetid(), + imod.cassette()); + } + + printf( + "[HGCalMappingIndexESSourceTester][analyze] Module and cells maps retrieved for HGCAL %d/%d valid modules " + "%d/%d valid cells", + validModules, + modules.view().metadata().size(), + validCells, + cells.view().metadata().size()); + + //test TrigDetId to MuxId mapping + //FIXME: this is for the moment disabled as extra input is needed from the backend regarding the MUX id - there is degeneracy + /* + const auto& tmap = [](auto geo2ele, auto ele2geo) { + //sizes must match + assert(geo2ele.size() == ele2geo.size()); + + //test uniqueness of keys + for (const auto& it : geo2ele) { + assert(ele2geo.count(it.second) == 1); + assert(ele2geo[it.second] == it.first); + } + + for (const auto& it : ele2geo) { + assert(geo2ele.count(it.second) == 1); + assert(geo2ele[it.second] == it.first); + } + + return true; + }; + + //apply test to Si + const auto& sigeo2ele = this->mapGeoToElectronics(modules, cells, true, false); + const auto& siele2geo = this->mapGeoToElectronics(modules, cells, false, false); + printf("[HGCalMappingIndexESSourceTester][produce] Silicon electronics<->geometry map\n"); + printf("\tID maps ele2geo=%ld ID maps geo2ele=%ld\n", siele2geo.size(), sigeo2ele.size()); + tmap(sigeo2ele, siele2geo); + + //apply test to SiPMs + const auto& sipmgeo2ele = this->mapGeoToElectronics(modules, cells, true, true); + const auto& sipmele2geo = this->mapGeoToElectronics(modules, cells, false, true); + printf("[HGCalMappingIndexESSourceTester][produce] SiPM-on-tile electronics<->geometry map\n"); + printf("\tID maps ele2geo=%ld ID maps geo2ele=%ld\n", sipmele2geo.size(), sipmgeo2ele.size()); + tmap(sipmgeo2ele, sipmele2geo); + */ + + //test dense index token + auto const& denseIndexInfo = iSetup.getData(denseIndexTkn_); + printf("Retrieved %d dense index info\n", denseIndexInfo.view().metadata().size()); + int nindices = denseIndexInfo.view().metadata().size(); + printf("fedId fedReadoutSeq detId muxid modix cellidx channel x y z\n"); + for (int i = 0; i < nindices; i++) { + auto row = denseIndexInfo.view()[i]; + printf("%d %d 0x%x 0x%x %d %d %d %f %f %f\n", + row.fedId(), + row.fedReadoutSeq(), + row.trigdetid(), + row.muxid(), + row.modInfoIdx(), + row.cellInfoIdx(), + row.TCNumber(), + row.x(), + row.y(), + row.z()); + } +} + +// +void HGCalMappingTriggerESSourceTester::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + descriptions.addWithDefaultLabel(desc); +} + +// +std::map HGCalMappingTriggerESSourceTester::mapGeoToElectronics( + const hgcal::HGCalMappingModuleTriggerParamHost& modules, + const hgcal::HGCalMappingCellParamHost& cells, + bool geo2ele, + bool sipm) { + //loop over different modules + std::map idmap; + uint32_t ndups(0); + printf("\n"); + for (int i = 0; i < modules.view().metadata().size(); i++) { + auto imod = modules.view()[i]; + + if (!imod.valid()) + continue; + + //require match to si or SiPM + if (sipm != imod.isSiPM()) + continue; + + if (imod.plane() == 0) { + printf("WARNING: found plane=0 for i1=%d i2=%d siPM=%d @ index=%i\n", imod.i1(), imod.i2(), imod.isSiPM(), i); + continue; + } + + //loop over cells in the module + for (int j = 0; j < cells.view().metadata().size(); j++) { + auto jcell = cells.view()[j]; + + //use only the information for cells which match the module type index + if (jcell.typeidx() != imod.typeidx()) + continue; + + //require that it's a valid cell + if (!jcell.valid()) + continue; + + //assert type of sensor + assert(imod.isSiPM() == jcell.isSiPM()); + + // make sure the cell is part of the module and it's not a calibration cell + if (jcell.t() != 1) + continue; + + uint32_t elecid = imod.muxid(); + + uint32_t geoid(0); + + if (sipm) { + geoid = ::hgcal::mappingtools::getSiPMDetId( + imod.zside(), imod.plane(), imod.i2(), imod.celltype(), jcell.i1(), jcell.i2()); + } else { + geoid = imod.trigdetid() + jcell.detid(); + } + + if (geo2ele) { + auto it = idmap.find(geoid); + ndups += (it != idmap.end()); + if (!sipm && it != idmap.end() && imod.plane() <= 26) { + HGCSiliconDetId detid(geoid); + printf("WARNING duplicate found for plane=%d u=%d v=%d cellU=%d cellV=%d valid=%d -> detid=0x%x\n", + imod.plane(), + imod.i1(), + imod.i2(), + jcell.i1(), + jcell.i2(), + jcell.valid(), + detid.rawId()); + } + } + if (!geo2ele) { + auto it = idmap.find(elecid); + ndups += (it != idmap.end()); + } + + //map + idmap[geo2ele ? geoid : elecid] = geo2ele ? elecid : geoid; + } + } + + if (ndups > 0) { + printf("[HGCalMappingTriggerESSourceTester][mapGeoToElectronics] found %d duplicates with geo2ele=%d for sipm=%d\n", + ndups, + geo2ele, + sipm); + } + + return idmap; +} + +// define this as a plug-in +DEFINE_FWK_MODULE(HGCalMappingTriggerESSourceTester); diff --git a/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc b/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc index 472a96cab9148..3b50a0e4ef020 100644 --- a/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc +++ b/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc @@ -88,7 +88,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { typecode.c_str(), idx, cellIdx.maxErx_[idx], - cellIdx.di_[idx].getMaxIndex(), + cellIdx.di_[idx].maxIndex(), cellIdx.offsets_[idx]); } diff --git a/Geometry/HGCalMapping/test/testMappingModuleIndexerTrigger_cfg.py b/Geometry/HGCalMapping/test/testMappingModuleIndexerTrigger_cfg.py new file mode 100644 index 0000000000000..92d6e1b63e98f --- /dev/null +++ b/Geometry/HGCalMapping/test/testMappingModuleIndexerTrigger_cfg.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms +process = cms.Process("TEST") + +import argparse as ap +parser = ap.ArgumentParser() +parser.add_argument('-modules','--modules',type=str, + default='Geometry/HGCalMapping/data/ModuleMaps/modulelocator_trigger_test.txt', + help='Path to module mapper. Absolute, or relative to CMSSW src directory.' + ) + +parser.add_argument('-sicells','--sicells',type=str, + default='Geometry/HGCalMapping/data/CellMaps/WaferCellMapTraces.txt', + help='Path to Si cell mapper. Absolute, or relative to CMSSW src directory.' + ) + +parser.add_argument('-sipmcells','--sipmcells',type=str, + default='Geometry/HGCalMapping/data/CellMaps/channels_sipmontile.hgcal.txt', + help='Path to SiPM-on-tile cell mapper. Absolute, or relative to CMSSW src directory.' + ) +options = parser.parse_args() + +process.source = cms.Source('EmptySource') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(1) +) + +# electronics mapping +from Geometry.HGCalMapping.hgcalmapping_cff import customise_hgcalmapper +process = customise_hgcalmapper(process, + modules=options.modules, + sicells=options.sicells, + sipmcells=options.sipmcells) + +# Geometry +process.load('Configuration.Geometry.GeometryExtended2025Reco_cff') + +# tester +process.tester = cms.EDAnalyzer('HGCalMappingTriggerESSourceTester') + +process.p = cms.Path(process.tester) diff --git a/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py b/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py index b7e1949b6e18d..d7a7418d70241 100644 --- a/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py +++ b/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py @@ -1,6 +1,7 @@ import FWCore.ParameterSet.Config as cms process = cms.Process("TEST") + from FWCore.ParameterSet.VarParsing import VarParsing options = VarParsing('python') options.register('modules','Geometry/HGCalMapping/data/ModuleMaps/modulelocator_test.txt',mytype=VarParsing.varType.string, @@ -11,7 +12,6 @@ info="Path to SiPM-on-tile cell mapper. Absolute, or relative to CMSSW src directory") options.register('offsetfile','Geometry/HGCalMapping/data/CellMaps/calibration_to_surrounding_offsetMap.txt',mytype=VarParsing.varType.string, info="Path to calibration-to-surrounding cell offset file. Absolute, or relative to CMSSW src directory") - options.parseArguments() process.source = cms.Source('EmptySource') diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h b/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h index 831fe00d1da3c..515052ba3a0be 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h @@ -88,7 +88,7 @@ namespace hgcal { float getPt(const DetId& id, const float& hitEnergy, const float& vertex_z = 0.) const; int getScintMaxIphi(const DetId& id) const; - inline const CaloGeometry* getGeometry() const { return geom_; }; + inline const CaloGeometry* geometry() const { return geom_; }; unsigned int lastLayerEE(bool nose = false) const { return (nose ? HFNoseDetId::HFNoseLayerEEmax : fhOffset_); } unsigned int lastLayerFH() const { return fhLastLayer_; } unsigned int firstLayerBH() const { return bhFirstLayer_; } diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc index 9a3f8b10e8773..ca458a6ccc37a 100644 --- a/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc @@ -84,7 +84,7 @@ class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSe const json mod_config_data = json::parse(modfile, nullptr, true, /*ignore_comments*/ true); // consistency check - uint32_t nfeds = moduleMap.getNumFEDs(); + uint32_t nfeds = moduleMap.numFEDs(); uint32_t ntot_mods = 0, ntot_rocs = 0; const std::vector fedkeys = {"mismatchPassthroughMode", "cbHeaderMarker", "slinkHeaderMarker"}; const std::vector modkeys = {"headerMarker", "CalibrationSC"}; @@ -97,10 +97,10 @@ class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSe // follow indexing by HGCalMappingModuleIndexer // HGCalConfiguration = container class holding FED structs of ECON-D structs of eRx structs std::unique_ptr config_ = std::make_unique(); - config_->feds.resize(moduleMap.getMaxFEDSize()); - for (std::size_t fedid = 0; fedid < moduleMap.getMaxFEDSize(); ++fedid) { + config_->feds.resize(moduleMap.maxFEDSize()); + for (std::size_t fedid = 0; fedid < moduleMap.maxFEDSize(); ++fedid) { // sanity checks - if (moduleMap.getFEDReadoutSequences()[fedid].readoutTypes_.empty()) // check if FED exists (non-empty) + if (moduleMap.fedReadoutSequences()[fedid].readoutTypes_.empty()) // check if FED exists (non-empty) continue; // skip non-existent FED const auto fedkey = hgcal::search_fedkey(fedid, fed_config_data, fedjson_); // search matching key hgcal::check_keys( @@ -116,7 +116,7 @@ class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSe slinkHeaderMarker_); // begin of event marker/identifier for S-link // loop over module typecodes (e.g. "ML-F3PT-TX-0003") - for (const auto& [typecode, ids] : moduleMap.getTypecodeMap()) { + for (const auto& [typecode, ids] : moduleMap.typecodeMap()) { auto [fedid_, imod] = ids; if (fedid_ != fedid) continue; @@ -158,14 +158,14 @@ class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSe } // consistency check - if (ntot_mods != moduleMap.getMaxModuleSize()) + if (ntot_mods != moduleMap.maxModuleSize()) edm::LogWarning("HGCalConfigurationESProducer") << "Total number of ECON-D modules found in JSON file " << modjson_ << " (" << ntot_mods - << ") does not match indexer (" << moduleMap.getMaxModuleSize() << ")"; - if (ntot_rocs != moduleMap.getMaxERxSize()) + << ") does not match indexer (" << moduleMap.maxModuleSize() << ")"; + if (ntot_rocs != moduleMap.maxERxSize()) edm::LogWarning("HGCalConfigurationESProducer") << "Total number of eRx half-ROCs found in JSON file " << modjson_ << " (" << ntot_rocs - << ") does not match indexer (" << moduleMap.getMaxERxSize() << ")"; + << ") does not match indexer (" << moduleMap.maxERxSize() << ")"; return config_; } // end of produce() diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc index 597022f1ab379..978953ed0bff9 100644 --- a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc @@ -95,7 +95,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { edm::LogInfo("HGCalCalibrationESProducer") << "produce: filename=" << filename_.fullPath().c_str(); // load dense indexing - const uint32_t nchans = moduleIndexer.getMaxDataSize(); // channel-level size + const uint32_t nchans = moduleIndexer.maxDataSize(); // channel-level size hgcalrechit::HGCalCalibParamHost product(nchans, cms::alpakatools::host()); // load calib parameters from JSON @@ -114,7 +114,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { const std::vector energylosses = energy_data["dEdx"].get>(); // loop over all module typecodes, e.g. "ML-F3PT-TX-0003" - for (const auto& [module, ids] : moduleIndexer.getTypecodeMap()) { + for (const auto& [module, ids] : moduleIndexer.typecodeMap()) { const auto [fedid, modid] = ids; // retrieve matching key (glob patterns allowed) diff --git a/RecoLocalCalo/HGCalRecAlgos/test/alpaka/HGCalRecHitESProducersTest.cc b/RecoLocalCalo/HGCalRecAlgos/test/alpaka/HGCalRecHitESProducersTest.cc index 656b89ef66d84..fd5384e6ebcf2 100644 --- a/RecoLocalCalo/HGCalRecAlgos/test/alpaka/HGCalRecHitESProducersTest.cc +++ b/RecoLocalCalo/HGCalRecAlgos/test/alpaka/HGCalRecHitESProducersTest.cc @@ -105,9 +105,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { std::string line = "HGCalRecHitESProducersTest::produce " + std::string(90, '-'); if (configWatcher_.check(iSetup)) { std::cout << line << std::endl; - std::cout << "HGCalRecHitESProducersTest::produce: moduleIndexer.getMaxDataSize()=" - << moduleIndexer.getMaxDataSize() << ", moduleIndexer.getMaxERxSize()=" << moduleIndexer.getMaxERxSize() - << std::endl; + std::cout << "HGCalRecHitESProducersTest::produce: moduleIndexer.maxDataSize()=" << moduleIndexer.maxDataSize() + << ", moduleIndexer.maxERxSize()=" << moduleIndexer.maxERxSize() << std::endl; // ESProducer for global HGCal configuration (structs) with header markers, etc. auto nfeds = config.feds.size(); // number of FEDs @@ -145,7 +144,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { int imod = 0; std::cout << "HGCalRecHitESProducersTest::produce: calibration constants per module:" << std::endl; std::cout << " imod typecode idx hex ADC_ped CM_slope CM_ped EM_scale" << std::endl; - for (const auto& [typecode, ids] : moduleIndexer.getTypecodeMap()) { + for (const auto& [typecode, ids] : moduleIndexer.typecodeMap()) { const auto [fedid, modid] = ids; if (imod >= maxmods_) break;