diff --git a/CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h b/CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h new file mode 100644 index 0000000000000..dd10355c18ccc --- /dev/null +++ b/CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h @@ -0,0 +1,29 @@ +#ifndef CondFormats_HGCalDenseIndexInfoRcd_h +#define CondFormats_HGCalDenseIndexInfoRcd_h +// -*- C++ -*- +// +// Package: CondFormats/DataRecord +// Class : HGCalDenseIndexInfoRcd +// +/**\class HGCalDenseIndexInfoRcd HGCalDenseIndexInfoRcd.h CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h + * + * Description: + * This record is used join information from the geometry and logical mapping + * This record depends on the HGCalElectronicsMappingRcd and CaloGeometryRecord + * + */ +// +// Author: Pedro Da Silva, Izaak Neutelings +// Created: Mon, 29 May 2023 09:13:07 GMT +// + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "FWCore/Utilities/interface/mplVector.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" + +class HGCalDenseIndexInfoRcd : public edm::eventsetup::DependentRecordImplementation< + HGCalDenseIndexInfoRcd, + edm::mpl::Vector > {}; + +#endif diff --git a/CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h b/CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h new file mode 100644 index 0000000000000..169d582ce4288 --- /dev/null +++ b/CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h @@ -0,0 +1,28 @@ +#ifndef CondFormats_HGCalModuleConfigurationRcd_h +#define CondFormats_HGCalModuleConfigurationRcd_h +// -*- C++ -*- +// +// Package: CondFormats/DataRecord +// Class : HGCalModuleConfigurationRcd +// +/**\class HGCalModuleConfigurationRcd HGCalModuleConfigurationRcd.h CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h + * + * Description: + * This record is used for passing the configuration parameters to the calibration step in RAW -> RECO, + * This record depends on the HGCalMappingModuleIndexerRcd. + * + */ +// +// Author: Pedro Da Silva, Izaak Neutelings +// Created: Mon, 29 May 2023 09:13:07 GMT +// + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "FWCore/Utilities/interface/mplVector.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" + +class HGCalModuleConfigurationRcd + : public edm::eventsetup::DependentRecordImplementation > {}; + +#endif diff --git a/CondFormats/DataRecord/src/HGCalDenseIndexInfoRcd.cc b/CondFormats/DataRecord/src/HGCalDenseIndexInfoRcd.cc new file mode 100644 index 0000000000000..c8689b1a37083 --- /dev/null +++ b/CondFormats/DataRecord/src/HGCalDenseIndexInfoRcd.cc @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// Package: CondFormats/DataRecord +// Class : HGCalDenseIndexInfoRcd +// +// Implementation: +// [Notes on implementation] +// +// Author: Pedro Da Silva, Izaak Neutelings +// Created: Mon, 29 May 2023 09:13:07 GMT + +#include "CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(HGCalDenseIndexInfoRcd); diff --git a/CondFormats/DataRecord/src/HGCalModuleConfigurationRcd.cc b/CondFormats/DataRecord/src/HGCalModuleConfigurationRcd.cc new file mode 100644 index 0000000000000..d79e2abf48e81 --- /dev/null +++ b/CondFormats/DataRecord/src/HGCalModuleConfigurationRcd.cc @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// Package: CondFormats/DataRecord +// Class : HGCalModuleConfigurationRcd +// +// Implementation: +// [Notes on implementation] +// +// Author: Pedro Da Silva, Izaak Neutelings +// Created: Mon, 29 May 2023 09:13:07 GMT + +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(HGCalModuleConfigurationRcd); diff --git a/CondFormats/HGCalObjects/BuildFile.xml b/CondFormats/HGCalObjects/BuildFile.xml index 6f6a7def437f1..5fef519096dd4 100644 --- a/CondFormats/HGCalObjects/BuildFile.xml +++ b/CondFormats/HGCalObjects/BuildFile.xml @@ -11,4 +11,4 @@ - \ No newline at end of file + diff --git a/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h b/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h new file mode 100644 index 0000000000000..19efd368dc3a8 --- /dev/null +++ b/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h @@ -0,0 +1,19 @@ +#ifndef CondFormats_HGCalObjects_interface_HGCalCalibrationParameterHost_h +#define CondFormats_HGCalObjects_interface_HGCalCalibrationParameterHost_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterSoA.h" + +namespace hgcalrechit { + + // SoA with channel-level calibration parameters in host memory: + // pedestal, CM_slope, CM_ped, BXm1_kappa + using HGCalCalibParamHost = PortableHostCollection; + + // SoA with ROC-level configuration parameters in host memory: + // gain + using HGCalConfigParamHost = PortableHostCollection; + +} // namespace hgcalrechit + +#endif // CondFormats_HGCalObjects_interface_HGCalCalibrationParameterHost_h diff --git a/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterSoA.h b/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterSoA.h new file mode 100644 index 0000000000000..7ea340a0b0eea --- /dev/null +++ b/CondFormats/HGCalObjects/interface/HGCalCalibrationParameterSoA.h @@ -0,0 +1,47 @@ +#ifndef CondFormats_HGCalObjects_interface_HGCalCalibrationParameterSoA_h +#define CondFormats_HGCalObjects_interface_HGCalCalibrationParameterSoA_h + +#include +#include + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +//#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" + +namespace hgcalrechit { + + // human-readable data type to replace bool for memcpy of vector<>::.data() + // NOTE: bool and byte have the same memory size + using mybool = std::byte; + + // Generate structure of channel-level arrays (SoA) layout with RecHit dataformat + GENERATE_SOA_LAYOUT(HGCalCalibParamSoALayout, + SOA_COLUMN(float, ADC_ped), // ADC pedestals, O(91) + SOA_COLUMN(float, Noise), // noise, O(3) + SOA_COLUMN(float, CM_slope), // common mode slope, O(0.25) + SOA_COLUMN(float, CM_ped), // common mode pedestal (offset), O(92) + SOA_COLUMN(float, BXm1_slope), // leakage correction from previous bunch, O(0.0) + SOA_COLUMN(float, ADCtofC), // ADC conversion to charge (fC), depends on gain (80, 160, 320 fC) + SOA_COLUMN(float, TOTtofC), // TOT conversion to charge (fC), depends on gain (80, 160, 320 fC) + SOA_COLUMN(float, TOT_ped), // TOT pedestal (offset), O(9.0) + SOA_COLUMN(float, TOT_lin), // threshold at which TOT is linear, O(200) + SOA_COLUMN(float, TOT_P0), // coefficient pol2 in nonlinear region, O(145) + SOA_COLUMN(float, TOT_P1), // coefficient pol2 in nonlinear region, O(1.0) + SOA_COLUMN(float, TOT_P2), // coefficient pol2 in nonlinear region, O(0.004) + SOA_COLUMN(float, TOAtops), // TOA conversion to time (ps) + SOA_COLUMN(float, MIPS_scale), // MIPS scale + SOA_COLUMN(mybool, valid) // if false: mask dead channel + ) + using HGCalCalibParamSoA = HGCalCalibParamSoALayout<>; + + // Generate structure of ROC-level arrays (SoA) layout with RecHit dataformat + GENERATE_SOA_LAYOUT(HGCalConfigParamSoALayout, + SOA_COLUMN(uint8_t, gain) // for ADC to charge (fC) conversion (80, 160, 320 fC) + ) + using HGCalConfigParamSoA = HGCalConfigParamSoALayout<>; + +} // namespace hgcalrechit + +#endif // CondFormats_HGCalObjects_interface_HGCalCalibrationParameterSoA_h diff --git a/CondFormats/HGCalObjects/interface/HGCalConfiguration.h b/CondFormats/HGCalObjects/interface/HGCalConfiguration.h new file mode 100644 index 0000000000000..a0dc76f53ca9c --- /dev/null +++ b/CondFormats/HGCalObjects/interface/HGCalConfiguration.h @@ -0,0 +1,68 @@ +// Authors: Izaak Neutelings (May 2024) +// Sources: https://docs.google.com/spreadsheets/d/13G7sOjssqw4B5AtOcQV3g0W01oZUOMM6Hm_DduxBEPU +#ifndef CondFormats_HGCalObjects_HGCalConfiguraton_h +#define CondFormats_HGCalObjects_HGCalConfiguraton_h +#include "CondFormats/Serialization/interface/Serializable.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include +#include + +// @short configuration for ECON eRX (one half of HGROC) +struct HGCalROCConfig { + uint32_t charMode; // characterization mode; determines data fields in ROC dataframe + uint8_t gain; // pre-amp gain used (1: 80 fC, 2: 160 fC, 4: 320 fC) + //uint32_t clockPhase; // fine adjustment of the phase within the 40 MHz + //uint32_t L1AcceptOffset; // coarse adjustment to get the peak in the right place + //uint32_t injChannels; // injected channels for injection scan: 2b word to identify if connected or not+info no capacitor chosen + //uint32_t injCharge; // injected charge for injection scan: convert it to a float in units of fC offline (DAC setting?) + COND_SERIALIZABLE; +}; + +// @short configuration for ECON-D module +struct HGCalECONDConfig { + //std::string typecode; + uint32_t headerMarker; // begin of event marker/identifier for ECON-D + uint32_t passThrough; //pass through mode (this is just as check as it'll be in the ECON-D header anyway) + std::vector rocs; + COND_SERIALIZABLE; +}; + +// @short configuration for FED +struct HGCalFedConfig { + bool mismatchPassthroughMode; // ignore ECON-D packet mismatches + uint32_t cbHeaderMarker; // begin of event marker/identifier for capture block + uint32_t slinkHeaderMarker; // begin of event marker/identifier for S-link + //uint32_t delay; // delay + std::vector econds; + COND_SERIALIZABLE; +}; + +/** + * @short Main HGCal configuration with a tree structure of vectors of + * HGCalFedConfig/HGCalECONDConfig/HGCalROCConfig structs as follows: + % config.feds[dense_fed_idx].econds[dense_econd_idx].rocs[dense_eRx_idx] + **/ +class HGCalConfiguration { +public: + std::vector feds; + //friend std::ostream& operator<< (std::ostream&, const HGCalConfiguration&); + +private: + COND_SERIALIZABLE; +}; + +inline std::ostream& operator<<(std::ostream& os, const HGCalConfiguration& config) { + uint32_t nfed = config.feds.size(); + uint32_t ntotmod = 0; + uint32_t ntotroc = 0; + for (auto const& fed : config.feds) { + ntotmod += fed.econds.size(); // number of ECON-D modules for this FED + for (auto const& mod : fed.econds) { + ntotroc += mod.rocs.size(); // number of eRx half-ROCs for this ECON-D module + } + } + os << "HGCalConfiguration(nfed=" << nfed << ",ntotmod=" << ntotmod << ",ntotroc=" << ntotroc << ")"; + return os; +} + +#endif diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h index 7f54585b067fe..bf60d7e3c3334 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h @@ -3,27 +3,31 @@ #include #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 "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" #include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/MessageLogger/interface/MessageLogger.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 HGCalFEDReadoutSequence_t { +struct HGCalFEDReadoutSequence { 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_, erxOffsets_, chDataOffsets_; + std::vector modOffsets_, erxOffsets_, chDataOffsets_, enabledErx_; COND_SERIALIZABLE; }; @@ -48,12 +52,13 @@ class HGCalMappingModuleIndexer { uint16_t econdIdx, uint32_t typecodeIdx, uint32_t nerx, - uint32_t nwords) { + uint32_t nwords, + std::string typecode = "") { //add fed if needed if (fedid >= fedReadoutSequences_.size()) { fedReadoutSequences_.resize(fedid + 1); } - HGCalFEDReadoutSequence_t &frs = fedReadoutSequences_[fedid]; + HGCalFEDReadoutSequence& frs = fedReadoutSequences_[fedid]; frs.id = fedid; //assign position, resize if needed, and fill the type code @@ -73,6 +78,20 @@ class HGCalMappingModuleIndexer { globalTypesCounter_[typecodeIdx]++; globalTypesNErx_[typecodeIdx] = nerx; globalTypesNWords_[typecodeIdx] = nwords; + + //add typecode string to map to retrieve fedId & modId later + if (typecode != "") { + if (typecodeMap_.find(typecode) != typecodeMap_.end()) { // found key + const auto& [fedid_, modid_] = typecodeMap_.at(typecode); // (fedId,modId) + edm::LogWarning("HGCalMappingModuleIndexer") + << "Found typecode " << typecode << " already in map (fedid,modid)=(" << fedid_ << "," << modid_ + << ")! Overwriting with (" << fedid << "," << idx << ")..."; + } + LogDebug("HGCalMappingModuleIndexer") + << "HGCalMappingModuleIndexer::processNewModule: Adding typecode=\"" << typecode << "\" with fedid=" << fedid + << ", idx=" << idx << " (will be re-indexed after finalize)"; + typecodeMap_[typecode] = std::make_pair(fedid, idx); + } } /** @@ -102,28 +121,34 @@ class HGCalMappingModuleIndexer { //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 indexing in the look-up table + 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 - std::remove_if( - fedit.readoutTypes_.begin(), fedit.readoutTypes_.end(), [&](int val) -> bool { return val == -1; }); + fedit.readoutTypes_.erase( + std::remove_if( + fedit.readoutTypes_.begin(), fedit.readoutTypes_.end(), [&](int val) -> bool { return val == -1; }), + fedit.readoutTypes_.end()); - //assign the final offsets at the different levels + //resize vectors to their final size and set final values size_t nmods = fedit.readoutTypes_.size(); fedit.modOffsets_.resize(nmods, 0); fedit.erxOffsets_.resize(nmods, 0); fedit.chDataOffsets_.resize(nmods, 0); + fedit.enabledErx_.resize(nmods, 0); + for (size_t i = 0; i < nmods; i++) { - uint32_t type_val = fedit.readoutTypes_[i]; + int type_val = fedit.readoutTypes_[i]; //module offset : global offset for this type + current index for this type uint32_t baseMod_offset = moduleOffsets_[type_val] + typeCounters[type_val]; @@ -139,6 +164,9 @@ class HGCalMappingModuleIndexer { uint32_t internalData_offset = globalTypesNWords_[type_val] * typeCounters[type_val]; fedit.chDataOffsets_[i] = baseData_offset + internalData_offset; + //enabled erx flags + //FIXME: assume all eRx are enabled now + fedit.enabledErx_[i] = (0b1 << globalTypesNErx_[type_val]) - 0b1; typeCounters[type_val]++; } } @@ -151,7 +179,6 @@ class HGCalMappingModuleIndexer { static std::pair convertTypeCode(std::string_view typecode) { if (typecode.size() < 5) throw cms::Exception("InvalidHGCALTypeCode") << typecode << " is invalid for decoding readout cell type"; - bool isSiPM = {typecode.find("TM") != std::string::npos ? true : false}; int celltype; if (isSiPM) { @@ -167,45 +194,112 @@ class HGCalMappingModuleIndexer { 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 nmod) const { - return fedReadoutSequences_[fedid].modOffsets_[nmod]; + uint32_t getIndexForModule(uint32_t fedid, uint32_t modid) const { + return fedReadoutSequences_[fedid].modOffsets_[modid]; }; uint32_t getIndexForModule(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx) const { - uint32_t nmod = denseIndexingFor(fedid, captureblockIdx, econdIdx); - return getIndexForModule(fedid, nmod); + uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx); + return getIndexForModule(fedid, modid); + }; + //uint32_t getIndexForModule(HGCalElectronicsId id) const { + // return getIndexForModule(id.localFEDId(),id.captureBlock(),id.econdIdx()); + //}; + uint32_t getIndexForModule(std::string const& typecode) const { + const auto& [fedid, modId] = getIndexForFedAndModule(typecode); // (fedId,modId) + return getIndexForModule(fedid, modId); }; - uint32_t getIndexForModuleErx(uint32_t fedid, uint32_t nmod, uint32_t erxidx) const { - return fedReadoutSequences_[fedid].erxOffsets_[nmod] + erxidx; + uint32_t getIndexForModuleErx(uint32_t fedid, uint32_t modid, uint32_t erxidx) const { + return fedReadoutSequences_[fedid].erxOffsets_[modid] + erxidx; }; uint32_t getIndexForModuleErx(uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx, uint32_t erxidx) const { - uint32_t nmod = denseIndexingFor(fedid, captureblockIdx, econdIdx); - return getIndexForModuleErx(fedid, nmod, erxidx); + uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx); + return getIndexForModuleErx(fedid, modid, erxidx); } - uint32_t getIndexForModuleData(uint32_t fedid, uint32_t nmod, uint32_t erxidx, uint32_t chidx) const { - return fedReadoutSequences_[fedid].chDataOffsets_[nmod] + erxidx * HGCalMappingCellIndexer::maxChPerErx_ + chidx; + uint32_t getIndexForModuleData(uint32_t fedid, uint32_t modid, uint32_t erxidx, uint32_t chidx) const { + return fedReadoutSequences_[fedid].chDataOffsets_[modid] + erxidx * HGCalMappingCellIndexer::maxChPerErx_ + chidx; }; uint32_t getIndexForModuleData( uint32_t fedid, uint16_t captureblockIdx, uint16_t econdIdx, uint32_t erxidx, uint32_t chidx) const { - uint32_t nmod = denseIndexingFor(fedid, captureblockIdx, econdIdx); - return getIndexForModuleData(fedid, nmod, erxidx, chidx); + uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx); + return getIndexForModuleData(fedid, modid, erxidx, chidx); }; + uint32_t getIndexForModuleData(HGCalElectronicsId id) const { + return id.isCM() ? getIndexForModuleErx(id.localFEDId(), id.captureBlock(), id.econdIdx(), id.econdeRx()) + : getIndexForModuleData( + id.localFEDId(), id.captureBlock(), id.econdIdx(), id.econdeRx(), id.halfrocChannel()); + }; + uint32_t getIndexForModuleData(std::string typecode) const { + const auto& [fedid, modid] = getIndexForFedAndModule(typecode); + return getIndexForModuleData(fedid, modid, 0, 0); + }; + std::pair 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("HGCalMappingModuleIndexer") + << "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) + }; + + /** + @short return number maximum index of FED, ECON-D Module, eRx ROC + */ + uint32_t getNFED() const { // return total number of FEDs that actually exist + return count_if(fedReadoutSequences_.begin(), fedReadoutSequences_.end(), [](auto fedrs) { + return fedrs.readoutTypes_.size() != 0; + }); + } + uint32_t getMaxFEDSize() const { return fedReadoutSequences_.size(); } + uint32_t getMaxModuleSize() const { + return maxModulesIdx_; + } // total number of ECON-Ds (useful for setting ECON-D SoA size) + uint32_t getMaxModuleSize(uint32_t fedid) const { // number of ECON-Ds for given FED id + return fedReadoutSequences_[fedid].readoutTypes_.size(); + } + uint32_t getMaxERxSize() const { + return maxErxIdx_; + } // total number of eRx half-ROCs (useful for setting config SoA size) + uint32_t getMaxERxSize(uint32_t fedid, uint32_t modid) const { // number of eRx half-ROCs for given FED & ECON-D ids + auto modtype_val = fedReadoutSequences_[fedid].readoutTypes_[modid]; + return globalTypesNErx_[modtype_val]; + } + uint32_t getMaxDataSize() const { + return maxDataIdx_; + } // total number of channels (useful for setting calib SoA size) - int getTypeForModule(uint32_t fedid, uint32_t nmod) const { return fedReadoutSequences_[fedid].readoutTypes_[nmod]; } + /** + @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 captureblockIdx, uint16_t econdIdx) const { - uint32_t nmod = denseIndexingFor(fedid, captureblockIdx, econdIdx); - return getTypeForModule(fedid, nmod); + uint32_t modid = denseIndexingFor(fedid, captureblockIdx, econdIdx); + return getTypeForModule(fedid, modid); } ///< internal indexer HGCalDenseIndexerBase modFedIndexer_; ///< the sequence of FED readout sequence descriptors - std::vector fedReadoutSequences_; + std::vector fedReadoutSequences_; ///< global counters for types of modules, number of e-Rx and words std::vector globalTypesCounter_, globalTypesNErx_, globalTypesNWords_; ///< base offsets to apply per module type with different granularity : module, e-Rx, channel data std::vector moduleOffsets_, erxOffsets_, dataOffsets_; ///< global counters (sizes of vectors) uint32_t nfeds_, maxDataIdx_, maxErxIdx_, maxModulesIdx_; + ///< map from module type code string to (fedIdx,modIdx) pair (implemented to retrieve dense index offset) + std::map> typecodeMap_; ///< max number of main buffers/capture blocks per FED constexpr static uint32_t maxCBperFED_ = 10; @@ -228,6 +322,20 @@ class HGCalMappingModuleIndexer { 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 (auto it : typecodeMap_) { + if (it.second != val) + continue; + typecodeMap_[it.first] = newval; + break; + } + } + COND_SERIALIZABLE; }; diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h b/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h similarity index 60% rename from CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h rename to CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h index 527f00047a2e2..f814c0db22cf6 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h @@ -1,5 +1,5 @@ -#ifndef CondFormats_HGCalObjects_interface_HGCalMappingParameterHostCollection_h -#define CondFormats_HGCalObjects_interface_HGCalMappingParameterHostCollection_h +#ifndef CondFormats_HGCalObjects_interface_HGCalMappingParameterHost_h +#define CondFormats_HGCalObjects_interface_HGCalMappingParameterHost_h #include "DataFormats/Portable/interface/PortableHostCollection.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h" @@ -7,11 +7,14 @@ namespace hgcal { // SoA with channel-level module mapping parameters in host memory: - using HGCalMappingModuleParamHostCollection = PortableHostCollection; + using HGCalMappingModuleParamHost = PortableHostCollection; // SoA with channel-level cell mapping parameters in host memory for both Si and SiPM channels: - using HGCalMappingCellParamHostCollection = PortableHostCollection; + using HGCalMappingCellParamHost = PortableHostCollection; + + //SoA with detailed indices corresponding to the dense index in use + using HGCalDenseIndexInfoHost = PortableHostCollection; } // namespace hgcal -#endif // CondFormats_HGCalObjects_interface_HGCalMappingParameterHostCollection_h +#endif // CondFormats_HGCalObjects_interface_HGCalMappingParameterHost_h diff --git a/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h b/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h index 378341c0b800c..910125c01894c 100644 --- a/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h +++ b/CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h @@ -10,7 +10,7 @@ namespace hgcal { - // Generate structure of channel-level arrays (SoA) layout with module mapping information + // Generate structure of module-level (ECON-D) arrays (SoA) layout with module mapping information GENERATE_SOA_LAYOUT(HGCalMappingModuleParamSoALayout, SOA_COLUMN(bool, valid), SOA_COLUMN(bool, zside), @@ -18,6 +18,7 @@ namespace hgcal { 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), @@ -51,6 +52,20 @@ namespace hgcal { SOA_COLUMN(uint32_t, detid)) using HGCalMappingCellParamSoA = HGCalMappingCellParamSoALayout<>; + // Generate structure of channel-level arrays (SoA) layout with module mapping information + GENERATE_SOA_LAYOUT(HGCalDenseIndexInfoSoALayout, + SOA_COLUMN(uint32_t, fedId), + SOA_COLUMN(uint32_t, fedReadoutSeq), + SOA_COLUMN(uint32_t, detid), + SOA_COLUMN(uint32_t, eleid), + SOA_COLUMN(uint32_t, modInfoIdx), + SOA_COLUMN(uint32_t, cellInfoIdx), + SOA_COLUMN(uint32_t, chNumber), + SOA_COLUMN(float, x), + SOA_COLUMN(float, y), + SOA_COLUMN(float, z)) + using HGCalDenseIndexInfoSoA = HGCalDenseIndexInfoSoALayout<>; + } // namespace hgcal #endif // CondFormats_HGCalObjects_interface_HGCalMappingParameterSoA_h diff --git a/CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h b/CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h new file mode 100644 index 0000000000000..a68ada0c974a2 --- /dev/null +++ b/CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h @@ -0,0 +1,23 @@ +#ifndef CondFormats_HGCalObjects_interface_alpaka_HGCalCalibrationParameterDevice_h +#define CondFormats_HGCalObjects_interface_alpaka_HGCalCalibrationParameterDevice_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterSoA.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcalrechit { + + using namespace ::hgcalrechit; + using HGCalCalibParamDevice = PortableCollection; + //using HGCalChannelConfigParamDevice = PortableCollection; + using HGCalConfigParamDevice = PortableCollection; + + } // namespace hgcalrechit + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif // CondFormats_HGCalObjects_interface_alpaka_HGCalCalibrationParameterDevice_h diff --git a/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.h b/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h similarity index 51% rename from CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.h rename to CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h index 02491ecc14548..4df23ca3c1d24 100644 --- a/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.h +++ b/CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h @@ -1,23 +1,25 @@ -#ifndef CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDeviceCollection_h -#define CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDeviceCollection_h +#ifndef CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDevice_h +#define CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDevice_h #include "DataFormats/Portable/interface/alpaka/PortableCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingParameterSoA.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" namespace ALPAKA_ACCELERATOR_NAMESPACE { namespace hgcal { - using HGCalMappingModuleParamDeviceCollection = PortableCollection<::hgcal::HGCalMappingModuleParamSoA>; - using HGCalMappingCellParamDeviceCollection = PortableCollection<::hgcal::HGCalMappingCellParamSoA>; + using HGCalMappingModuleParamDevice = PortableCollection<::hgcal::HGCalMappingModuleParamSoA>; + using HGCalMappingCellParamDevice = PortableCollection<::hgcal::HGCalMappingCellParamSoA>; + using HGCalDenseIndexInfoDevice = PortableCollection<::hgcal::HGCalDenseIndexInfoSoA>; - using HGCalMappingModuleParamHostCollection = ::hgcal::HGCalMappingModuleParamHostCollection; - using HGCalMappingCellParamHostCollection = ::hgcal::HGCalMappingCellParamHostCollection; + using HGCalMappingModuleParamHost = ::hgcal::HGCalMappingModuleParamHost; + using HGCalMappingCellParamHost = ::hgcal::HGCalMappingCellParamHost; + using HGCalDenseIndexInfoHost = ::hgcal::HGCalDenseIndexInfoHost; } // namespace hgcal } // namespace ALPAKA_ACCELERATOR_NAMESPACE -#endif // CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDeviceCollection_h +#endif // CondFormats_HGCalObjects_interface_alpaka_HGCalMappingParameterDevice_h diff --git a/CondFormats/HGCalObjects/src/ES_HGCalMappingParameter.cc b/CondFormats/HGCalObjects/src/ES_HGCalMappingParameter.cc deleted file mode 100644 index f9e2335d99eda..0000000000000 --- a/CondFormats/HGCalObjects/src/ES_HGCalMappingParameter.cc +++ /dev/null @@ -1,5 +0,0 @@ -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h" -#include "FWCore/Utilities/interface/typelookup.h" - -TYPELOOKUP_DATA_REG(hgcal::HGCalMappingModuleParamHostCollection); -TYPELOOKUP_DATA_REG(hgcal::HGCalMappingCellParamHostCollection); diff --git a/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc b/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc new file mode 100644 index 0000000000000..1c74c1972ab5f --- /dev/null +++ b/CondFormats/HGCalObjects/src/HGCalMappingParameterHost.cc @@ -0,0 +1,6 @@ +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(hgcal::HGCalMappingModuleParamHost); +TYPELOOKUP_DATA_REG(hgcal::HGCalMappingCellParamHost); +TYPELOOKUP_DATA_REG(hgcal::HGCalDenseIndexInfoHost); diff --git a/CondFormats/HGCalObjects/src/T_EventSetup_HGCalCalibrationParameterHost.cc b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalCalibrationParameterHost.cc new file mode 100644 index 0000000000000..d88467f732756 --- /dev/null +++ b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalCalibrationParameterHost.cc @@ -0,0 +1,5 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" + +TYPELOOKUP_DATA_REG(hgcalrechit::HGCalCalibParamHost); +TYPELOOKUP_DATA_REG(hgcalrechit::HGCalConfigParamHost); diff --git a/CondFormats/HGCalObjects/src/T_EventSetup_HGCalConfiguration.cc b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalConfiguration.cc new file mode 100644 index 0000000000000..0916ead29bcca --- /dev/null +++ b/CondFormats/HGCalObjects/src/T_EventSetup_HGCalConfiguration.cc @@ -0,0 +1,4 @@ +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(HGCalConfiguration); diff --git a/CondFormats/HGCalObjects/src/alpaka/ES_HGCalMappingParameter.cc b/CondFormats/HGCalObjects/src/alpaka/ES_HGCalMappingParameter.cc deleted file mode 100644 index b34eb21327214..0000000000000 --- a/CondFormats/HGCalObjects/src/alpaka/ES_HGCalMappingParameter.cc +++ /dev/null @@ -1,5 +0,0 @@ -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/typelookup.h" -#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.h" - -TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingModuleParamDeviceCollection); -TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingCellParamDeviceCollection); diff --git a/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc b/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc new file mode 100644 index 0000000000000..fb851b66eb8fe --- /dev/null +++ b/CondFormats/HGCalObjects/src/alpaka/HGCalMappingParameterDevice.cc @@ -0,0 +1,6 @@ +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/typelookup.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h" + +TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingModuleParamDevice); +TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalMappingCellParamDevice); +TYPELOOKUP_ALPAKA_DATA_REG(hgcal::HGCalDenseIndexInfoDevice); diff --git a/CondFormats/HGCalObjects/src/alpaka/T_EventSetup_HGCalCalibrationParameterDevice.cc b/CondFormats/HGCalObjects/src/alpaka/T_EventSetup_HGCalCalibrationParameterDevice.cc new file mode 100644 index 0000000000000..ab849e7d65fc2 --- /dev/null +++ b/CondFormats/HGCalObjects/src/alpaka/T_EventSetup_HGCalCalibrationParameterDevice.cc @@ -0,0 +1,5 @@ +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/typelookup.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" + +TYPELOOKUP_ALPAKA_DATA_REG(hgcalrechit::HGCalCalibParamDevice); +TYPELOOKUP_ALPAKA_DATA_REG(hgcalrechit::HGCalConfigParamDevice); diff --git a/CondFormats/HGCalObjects/src/classes_def.xml b/CondFormats/HGCalObjects/src/classes_def.xml index c0b18395af14f..bd8c4b32d8981 100644 --- a/CondFormats/HGCalObjects/src/classes_def.xml +++ b/CondFormats/HGCalObjects/src/classes_def.xml @@ -1,23 +1,20 @@ - - - - + - + - + - - + + @@ -25,4 +22,35 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CondFormats/HGCalObjects/src/headers.h b/CondFormats/HGCalObjects/src/headers.h index 088038e48415b..824c64d2c25e6 100644 --- a/CondFormats/HGCalObjects/src/headers.h +++ b/CondFormats/HGCalObjects/src/headers.h @@ -1,3 +1,4 @@ +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" #include "CondFormats/HGCalObjects/interface/HGCalDenseIndexerBase.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" \ No newline at end of file diff --git a/CondFormats/HGCalObjects/test/BuildFile.xml b/CondFormats/HGCalObjects/test/BuildFile.xml index b52096ccaba6e..17615782f0e04 100644 --- a/CondFormats/HGCalObjects/test/BuildFile.xml +++ b/CondFormats/HGCalObjects/test/BuildFile.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc b/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc index e7d255e99b29b..aa6bfa4c577a5 100644 --- a/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc +++ b/CondFormats/HGCalObjects/test/testSerializationHGCalCondDataFormats.cc @@ -5,7 +5,7 @@ int main() { //dense indexers testSerialization(); testSerialization(); - testSerialization(); + testSerialization(); testSerialization(); return 0; diff --git a/DataFormats/HGCalDigi/BuildFile.xml b/DataFormats/HGCalDigi/BuildFile.xml index 27ab1f668924d..1480d16e3a33a 100644 --- a/DataFormats/HGCalDigi/BuildFile.xml +++ b/DataFormats/HGCalDigi/BuildFile.xml @@ -1,6 +1,11 @@ + + + + + diff --git a/DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h b/DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h index f9f9925884a0f..b4f34c7130866 100644 --- a/DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h +++ b/DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h @@ -38,7 +38,6 @@ class HGCROCChannelDataFrame { HGCROCChannelDataFrame(uint32_t value) : id_(0), value_(value) {} HGCROCChannelDataFrame(const D& id, uint32_t value) : id_(id), value_(value) {} HGCROCChannelDataFrame(const HGCROCChannelDataFrame& o) : id_(o.id_), value_(o.value_) {} - HGCROCChannelDataFrame& operator=(const HGCROCChannelDataFrame&) = default; /** @short det id @@ -102,7 +101,7 @@ class HGCROCChannelDataFrame { uint32_t raw() const { return value_; } bool tc() const { return flag2(); } bool tp() const { return flag1(); } - uint16_t tctp() const { return (tc() << 1) | tp(); } + uint8_t tctp() const { return (tc() << 1) | tp(); } uint16_t adc(bool charMode = false) const { return charMode ? packet3() : (tc() ? 0 : packet2()); } uint16_t adcm1(bool charMode = false) const { return charMode ? 0 : packet3(); } uint16_t tot(bool charMode = false) const { diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h b/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h index cc136d1ff7903..bbdc752ed70fc 100644 --- a/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h +++ b/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h @@ -8,9 +8,9 @@ #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" typedef HGCROCChannelDataFrame HGCROCChannelDataFrameSpec; -typedef edm::SortedCollection HGCalDigiCollection; +typedef edm::SortedCollection HGCalROCChannelDigiCollection; typedef HGCROCChannelDataFrame HGCROCChannelDataFrameElecSpec; -typedef edm::SortedCollection HGCalElecDigiCollection; +typedef edm::SortedCollection HGCalElecROCChannelDigiCollection; #endif diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiHost.h b/DataFormats/HGCalDigi/interface/HGCalDigiHost.h new file mode 100644 index 0000000000000..1df5c54b8dcec --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalDigiHost.h @@ -0,0 +1,14 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalDigiHost_h +#define DataFormats_HGCalDigi_interface_HGCalDigiHost_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" + +namespace hgcaldigi { + + // SoA with x, y, z, id fields in host memory + using HGCalDigiHost = PortableHostCollection; + +} // namespace hgcaldigi + +#endif // DataFormats_HGCalDigi_interface_HGCalDigiHost_h diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiSoA.h b/DataFormats/HGCalDigi/interface/HGCalDigiSoA.h new file mode 100644 index 0000000000000..3457a3b38667f --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalDigiSoA.h @@ -0,0 +1,26 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalDigiSoA_h +#define DataFormats_HGCalDigi_interface_HGCalDigiSoA_h + +#include +#include + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +namespace hgcaldigi { + + // Generate structure of arrays (SoA) layout with Digi dataformat + GENERATE_SOA_LAYOUT(HGCalDigiSoALayout, + SOA_COLUMN(uint8_t, tctp), + SOA_COLUMN(uint16_t, adcm1), + SOA_COLUMN(uint16_t, adc), + SOA_COLUMN(uint16_t, tot), + SOA_COLUMN(uint16_t, toa), + SOA_COLUMN(uint16_t, cm), + SOA_COLUMN(uint16_t, flags)) + using HGCalDigiSoA = HGCalDigiSoALayout<>; + +} // namespace hgcaldigi + +#endif // DataFormats_HGCalDigi_interface_HGCalDigiSoA_h diff --git a/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h b/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h new file mode 100644 index 0000000000000..4e6e970475ed3 --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h @@ -0,0 +1,14 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalECONDPacketInfoHost_h +#define DataFormats_HGCalDigi_interface_HGCalECONDPacketInfoHost_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h" + +namespace hgcaldigi { + + // SoA with x, y, z, id fields in host memory + using HGCalECONDPacketInfoHost = PortableHostCollection; + +} // namespace hgcaldigi + +#endif diff --git a/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h b/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h new file mode 100644 index 0000000000000..96e4864c9085b --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h @@ -0,0 +1,77 @@ +#ifndef DataFormats_HGCalDigi_interface_HGCalECONDPacketInfoSoA_h +#define DataFormats_HGCalDigi_interface_HGCalECONDPacketInfoSoA_h + +#include // for uint8_t + +#include +#include + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +namespace hgcaldigi { + + // use Matrix for common modes + using Matrix = Eigen :: Matrix < uint16_t , 12 , 2 >; + // enum for getting ECONDFlag + namespace ECONDFlag { + constexpr uint8_t BITT_POS = 0, BITM_POS = 1, EBO_POS = 2, EBO_MASK = 0b11, HT_POS = 4, HT_MASK = 0b11, + BITE_POS = 6, BITS_POS = 7; + } // namespace ECONDFlag + + // functions to parse ECONDFlag + inline bool truncatedFlag(uint8_t econdFlag) { return ((econdFlag >> hgcaldigi::ECONDFlag::BITT_POS) & 0b1); } + inline bool matchFlag(uint8_t econdFlag) { return ((econdFlag >> hgcaldigi::ECONDFlag::BITM_POS) & 0b1); } + inline uint8_t eboFlag(uint8_t econdFlag) { + return ((econdFlag >> hgcaldigi::ECONDFlag::EBO_POS) & hgcaldigi::ECONDFlag::EBO_MASK); + } + inline uint8_t htFlag(uint8_t econdFlag) { + return ((econdFlag >> hgcaldigi::ECONDFlag::HT_POS) & hgcaldigi::ECONDFlag::HT_MASK); + } + inline bool expectedFlag(uint8_t econdFlag) { return ((econdFlag >> hgcaldigi::ECONDFlag::BITE_POS) & 0b1); } + inline bool StatFlag(uint8_t econdFlag) { return ((econdFlag >> hgcaldigi::ECONDFlag::BITS_POS) & 0b1); } + + // generate structure of arrays (SoA) layout with Digi dataformat + GENERATE_SOA_LAYOUT(HGCalECONDPacketInfoSoALayout, + // Capture block information: + // 0b000: Normal packet + // 0b001: No ECOND packet. Packet was detected and discarded because too large (>250) + // 0b010: Packet with payload CRC error + // 0b011: Packet with EventID mismatch. + // 0b100: No ECOND packet. The event builder state machine timed-out. + // 0b101: No ECOND packet due to BCID and/or OrbitID mismatch. + // 0b110: No ECOND packet. Packet was detected but was discarded due to Main Buffer overflow. + SOA_COLUMN(uint8_t, cbFlag), //cbflag + // ECON-D header information + // bit 0: Truncation flag + // bit 1: Match flag + // bit 2-3: E/B/O bits + // bit 4-5: H/T bits + // bit 6: Expected flag + // bit 7: logical OR of Stat for all active eRx + SOA_COLUMN(uint8_t, econdFlag), //econdFlag + // Exception flag + // 0: Normal + // 1: Wrong S-Link header marker + // 2: Wrong Capture block header marker + // These will be saved to the first ECON-D in the block + // 3: Wrong ECON-D header marker + // 4: ECON-D payload length overflow(>469) + // 5: unpacked ECON-D length and payload length not match + // 6: S-Link trailer location error + // 7: S-Link End earlier + SOA_COLUMN(uint8_t, exception), + // Location + // If exception found before ECON-D, this would be 0 + // Otherwise the 64b index of ECON-D header + SOA_COLUMN(uint32_t, location), + // Payload length + // If exception found before ECON-D, this would be 0 + // Otherwise the payload length of the ECON-D + SOA_COLUMN(uint16_t, payloadLength), + SOA_EIGEN_COLUMN(Matrix, cm)) + using HGCalECONDPacketInfoSoA = HGCalECONDPacketInfoSoALayout<>; +} // namespace hgcaldigi + +#endif \ No newline at end of file diff --git a/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h b/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h new file mode 100644 index 0000000000000..2ae4bc222184a --- /dev/null +++ b/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h @@ -0,0 +1,74 @@ +#ifndef DataFormats_HGCalDigi_HGCalRawDataDefinitions_h +#define DataFormats_HGCalDigi_HGCalRawDataDefinitions_h + +#include // for uint8_t + +namespace hgcal { + namespace econd { + namespace ToTStatus { + constexpr uint8_t ZeroSuppressed = 0x0, noZeroSuppressed_TOASuppressed = 0x1, invalid = 0x2, AutomaticFull = 0x3; + } // namespace ToTStatus + } // namespace econd + + namespace backend { + namespace ECONDPacketStatus { + constexpr uint8_t Normal = 0x0, PayloadTooLarge = 0x1, PayloadCRCError = 0x2, EventIDMismatch = 0x3, + EBTimeout = 0x4, BCIDOrbitIDMismatch = 0x5, MainBufferOverflow = 0x6, InactiveECOND = 0x7; + } // namespace ECONDPacketStatus + } // namespace backend + + namespace ECOND_FRAME { + constexpr uint32_t HEADER_POS = 23, HEADER_MASK = 0x1ff, PAYLOAD_POS = 14, PAYLOAD_MASK = 0x1ff, BITP_POS = 13, + BITE_POS = 12, HT_MASK = 0x3, HT_POS = 10, EBO_MASK = 0x3, EBO_POS = 8, BITM_POS = 7, + BITT_POS = 6, EHHAM_MASK = 0x3f, EHHAM_POS = 0, BX_POS = 20, BX_MASK = 0xfff, L1A_POS = 14, + L1A_MASK = 0x3f, ORBIT_POS = 11, ORBIT_MASK = 0x7, BITS_POS = 10, RR_MASK = 0x3, RR_POS = 8, + EHCRC_MASK = 0xff, EHCRC_POS = 0, ERXSTAT_POS = 29, ERXSTAT_MASK = 0x7, ERXHAM_POS = 26, + ERXHAM_MASK = 0x7, ERXFORMAT_POS = 25, ERXFORMAT_MASK = 0x1, COMMONMODE0_POS = 15, + COMMONMODE0_MASK = 0x3ff, COMMONMODE1_POS = 5, COMMONMODE1_MASK = 0x3ff, CHMAP32_POS = 0, + CHMAP32_MASK = 0x1f, CHMAP0_POS = 0, CHMAP0_MASK = 0xffffffff, ERX_E_POS = 4, ERX_E_MASK = 1; + } // namespace ECOND_FRAME + + namespace BACKEND_FRAME { + constexpr uint32_t CAPTUREBLOCK_RESERVED_MASK = 0x7f, CAPTUREBLOCK_RESERVED_POS = 25, CAPTUREBLOCK_BC_MASK = 0xfff, + CAPTUREBLOCK_BC_POS = 13, CAPTUREBLOCK_EC_MASK = 0x7f, CAPTUREBLOCK_EC_POS = 7, + CAPTUREBLOCK_OC_MASK = 0x7, CAPTUREBLOCK_OC_POS = 4, SLINK_BOE_MASK = 0xff, SLINK_BOE_POS = 24, + SLINK_V_MASK = 0xf, SLINK_V_POS = 19, SLINK_R8_MASK = 0xff, SLINK_R8_POS = 11, + SLINK_GLOBAL_EVENTID_MSB_MASK = 0xfff, SLINK_GLOBAL_EVENTID_MSB_POS = 0, + SLINK_GLOBAL_EVENTID_LSB_MASK = 0xffffffff, SLINK_GLOBAL_EVENTID_LSB_POS = 0, + SLINK_R6_MASK = 0x3f, SLINK_R6_POS = 25, SLINK_CONTENTID_MASK = 0x3FFFFFF, + SLINK_CONTENTID_POS = 0, SLINK_SOURCEID_MASK = 0xffffffff, SLINK_SOURCEID_POS = 0, + SLINK_EOE_MASK = 0xff, SLINK_EOE_POS = 23, SLINK_DAQCRC_MASK = 0xffff, SLINK_DAQCRC_POS = 7, + SLINK_TRAILERR_MASK = 0xff, SLINK_TRAILERR_POS = 0, SLINK_EVLENGTH_MASK = 0xfffff, + SLINK_EVLENGTH_POS = 11, SLINK_BXID_MASK = 0xfff, SLINK_BXID_POS = 0, + SLINK_ORBID_MASK = 0xffffffff, SLINK_ORBID_POS = 0, SLINK_CRC_MASK = 0xffff, SLINK_CRC_POS = 15, + SLINK_STATUS_MASK = 0xffff, SLINK_STATUS_POS = 0; + } // namespace BACKEND_FRAME + + namespace DIGI_FLAG { + constexpr uint16_t + // flags for normal ECON-D + FULL_READOUT = 0x0000, + ZS_ADCm1 = 0x0001, ZS_ToA = 0x0002, ZS_ToA_ADCm1 = 0x0003, Invalid = 0x0004, + // flags for passthrough ECON-D + Normal = 0x8000, Characterization = 0x8001, + // flag for digi not in raw data + NotAvailable = 0xFFFF; + } // namespace DIGI_FLAG + namespace UNPACKER_STAT { + //This aligns with the definitons in HGCalECONDPacketInfoSoA + // 0: Normal + // 1: Wrong S-Link header marker + // 2: Wrong Capture block header marker + // 3: Wrong ECON-D header marker + // 4: ECON-D payload length overflow(>469) + // 5: unpacked ECON-D length and payload length not match + // 6: S-Link trailer location error + // 7: S-Link End earlier + constexpr uint8_t Normal = 0, WrongSLinkHeader = 1, WrongCaptureBlockHeader = 2, WrongECONDHeader = 3, + ECONDPayloadLengthOverflow = 4, ECONDPayloadLengthMismatch = 5, WrongSLinkTrailer = 6, + EarlySLinkEnd = 7; + } // namespace UNPACKER_STAT + +} // namespace hgcal + +#endif diff --git a/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h b/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h new file mode 100644 index 0000000000000..86b1abc84d47d --- /dev/null +++ b/DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h @@ -0,0 +1,23 @@ +#ifndef DataFormats_HGCalDigi_interface_alpaka_HGCalDigiDevice_h +#define DataFormats_HGCalDigi_interface_alpaka_HGCalDigiDevice_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.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 HGCalDigiDevice = PortableCollection; + + } // namespace hgcaldigi + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif // DataFormats_HGCalDigi_interface_alpaka_HGCalDigiDevice_h diff --git a/DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h b/DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h new file mode 100644 index 0000000000000..c701d5adf1476 --- /dev/null +++ b/DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h @@ -0,0 +1,23 @@ +#ifndef DataFormats_HGCalDigi_interface_alpaka_HGCalECONDPacketInfoDevice_h +#define DataFormats_HGCalDigi_interface_alpaka_HGCalECONDPacketInfoDevice_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.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 HGCalECONDPacketInfoDevice = PortableCollection; + + } // namespace hgcaldigi + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h b/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h new file mode 100644 index 0000000000000..4c253f83e0c19 --- /dev/null +++ b/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml b/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml new file mode 100644 index 0000000000000..3c526d77bafb0 --- /dev/null +++ b/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h b/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h new file mode 100644 index 0000000000000..4c253f83e0c19 --- /dev/null +++ b/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml b/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml new file mode 100644 index 0000000000000..7db73421ea557 --- /dev/null +++ b/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/DataFormats/HGCalDigi/src/classes.cc b/DataFormats/HGCalDigi/src/classes.cc new file mode 100644 index 0000000000000..aed0fcc8c3e5f --- /dev/null +++ b/DataFormats/HGCalDigi/src/classes.cc @@ -0,0 +1,6 @@ +#include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h" + +SET_PORTABLEHOSTCOLLECTION_READ_RULES(hgcaldigi::HGCalDigiHost); +SET_PORTABLEHOSTCOLLECTION_READ_RULES(hgcaldigi::HGCalECONDPacketInfoHost); \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/classes.h b/DataFormats/HGCalDigi/src/classes.h index 0bc1906d9b95b..2bc524c488b4b 100644 --- a/DataFormats/HGCalDigi/src/classes.h +++ b/DataFormats/HGCalDigi/src/classes.h @@ -1,8 +1,11 @@ #include #include - #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" #include "DataFormats/HGCalDigi/interface/HGCalDigiCollections.h" #include "DataFormats/HGCalDigi/interface/PHGCSimAccumulator.h" #include "DataFormats/HGCalDigi/interface/HGCalRawDataEmulatorInfo.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoSoA.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/classes_def.xml b/DataFormats/HGCalDigi/src/classes_def.xml index 5777230db9132..09afbecec4f41 100644 --- a/DataFormats/HGCalDigi/src/classes_def.xml +++ b/DataFormats/HGCalDigi/src/classes_def.xml @@ -1,31 +1,31 @@ - - - - - - + + + - - - + + + + + + - - + + - - + + - - + + - - - - - - + + + + + + @@ -40,4 +40,20 @@ + + + + + + + + + + + + + + + + diff --git a/DataFormats/HGCalRecHit/BuildFile.xml b/DataFormats/HGCalRecHit/BuildFile.xml new file mode 100644 index 0000000000000..e6d9b8d540da5 --- /dev/null +++ b/DataFormats/HGCalRecHit/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h b/DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h new file mode 100644 index 0000000000000..1a29f8f54c8d1 --- /dev/null +++ b/DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h @@ -0,0 +1,14 @@ +#ifndef DataFormats_HGCalRecHit_interface_HGCalRecHitHost_h +#define DataFormats_HGCalRecHit_interface_HGCalRecHitHost_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h" + +namespace hgcalrechit { + + // SoA with x, y, z, id fields in host memory + using HGCalRecHitHost = PortableHostCollection; + +} // namespace hgcalrechit + +#endif // DataFormats_HGCalRecHit_interface_HGCalRecHitHost_h diff --git a/DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h b/DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h new file mode 100644 index 0000000000000..375f537596fdb --- /dev/null +++ b/DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h @@ -0,0 +1,24 @@ +#ifndef DataFormats_HGCalRecHit_interface_HGCalRecHitSoA_h +#define DataFormats_HGCalRecHit_interface_HGCalRecHitSoA_h + +#include +#include + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +namespace hgcalrechit { + + // Generate structure of arrays (SoA) layout with RecHit dataformat + GENERATE_SOA_LAYOUT(HGCalRecHitSoALayout, + SOA_COLUMN(double, energy), + SOA_COLUMN(double, time), + SOA_COLUMN(uint16_t, flags)) + using HGCalRecHitSoA = HGCalRecHitSoALayout<>; + + enum HGCalRecHitFlags { Normal = 0x0, EnergyInvalid = 0x1, TimeInvalid = 0x2 }; + +} // namespace hgcalrechit + +#endif // DataFormats_HGCalRecHit_interface_HGCalRecHitSoA_h diff --git a/DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h b/DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h new file mode 100644 index 0000000000000..158b8a1f90107 --- /dev/null +++ b/DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h @@ -0,0 +1,23 @@ +#ifndef DataFormats_HGCalRecHit_interface_alpaka_HGCalRecHitDevice_h +#define DataFormats_HGCalRecHit_interface_alpaka_HGCalRecHitDevice_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcalrechit { + + // make the names from the top-level hgcalrechit namespace visible for unqualified lookup + // inside the ALPAKA_ACCELERATOR_NAMESPACE::hgcalrechit namespace + using namespace ::hgcalrechit; + + // SoA in device global memory + using HGCalRecHitDevice = PortableCollection; + + } // namespace hgcalrechit + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif // DataFormats_HGCalRecHit_interface_alpaka_HGCalRecHitDevice_h diff --git a/DataFormats/HGCalRecHit/src/alpaka/classes_cuda.h b/DataFormats/HGCalRecHit/src/alpaka/classes_cuda.h new file mode 100644 index 0000000000000..0f81a12c9ec38 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/alpaka/classes_cuda.h @@ -0,0 +1,4 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h" +#include "DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h" diff --git a/DataFormats/HGCalRecHit/src/alpaka/classes_cuda_def.xml b/DataFormats/HGCalRecHit/src/alpaka/classes_cuda_def.xml new file mode 100644 index 0000000000000..aa9fef56baae9 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/alpaka/classes_cuda_def.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/DataFormats/HGCalRecHit/src/alpaka/classes_rocm.h b/DataFormats/HGCalRecHit/src/alpaka/classes_rocm.h new file mode 100644 index 0000000000000..0f81a12c9ec38 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/alpaka/classes_rocm.h @@ -0,0 +1,4 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h" +#include "DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h" diff --git a/DataFormats/HGCalRecHit/src/alpaka/classes_rocm_def.xml b/DataFormats/HGCalRecHit/src/alpaka/classes_rocm_def.xml new file mode 100644 index 0000000000000..e3bb4ace8edf0 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/alpaka/classes_rocm_def.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/DataFormats/HGCalRecHit/src/classes.cc b/DataFormats/HGCalRecHit/src/classes.cc new file mode 100644 index 0000000000000..ea06afce36eeb --- /dev/null +++ b/DataFormats/HGCalRecHit/src/classes.cc @@ -0,0 +1,4 @@ +#include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h" + +SET_PORTABLEHOSTCOLLECTION_READ_RULES(hgcalrechit::HGCalRecHitHost); \ No newline at end of file diff --git a/DataFormats/HGCalRecHit/src/classes.h b/DataFormats/HGCalRecHit/src/classes.h new file mode 100644 index 0000000000000..94827204391f3 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/classes.h @@ -0,0 +1,3 @@ +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitSoA.h" diff --git a/DataFormats/HGCalRecHit/src/classes_def.xml b/DataFormats/HGCalRecHit/src/classes_def.xml new file mode 100644 index 0000000000000..810d24bfc9a67 --- /dev/null +++ b/DataFormats/HGCalRecHit/src/classes_def.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/EventFilter/HGCalRawToDigi/BuildFile.xml b/EventFilter/HGCalRawToDigi/BuildFile.xml index 3ea21ed517ee8..71d70baae4e7c 100644 --- a/EventFilter/HGCalRawToDigi/BuildFile.xml +++ b/EventFilter/HGCalRawToDigi/BuildFile.xml @@ -1,3 +1,6 @@ + + + diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h b/EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h deleted file mode 100644 index 6f7dd3d73b3c3..0000000000000 --- a/EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Laurent Forthomme, CERN - * - ****************************************************************************/ - -#ifndef EventFilter_HGCalRawToDigi_HGCalFrameGenerator_h -#define EventFilter_HGCalRawToDigi_HGCalFrameGenerator_h - -#include "DataFormats/HGCalDigi/interface/HGCalRawDataEmulatorInfo.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h" -#include "EventFilter/HGCalRawToDigi/interface/SlinkTypes.h" - -#include -#include - -namespace edm { - class ParameterSet; - class ParameterSetDescription; -} // namespace edm -namespace CLHEP { - class HepRandomEngine; -} - -namespace hgcal { - namespace econd { - class Emulator; - } - /// A S-link/ECON-D payload generator helper - class HGCalFrameGenerator { - public: - explicit HGCalFrameGenerator(const edm::ParameterSet&); - - static edm::ParameterSetDescription description(); - - /// Set the random number generator engine - void setRandomEngine(CLHEP::HepRandomEngine& rng); - /// Set the emulation source for ECON-D frames - void setEmulator(econd::Emulator&); - - /// Produce a S-link event from an emulated event - std::vector produceSlinkEvent(unsigned int fed_id) const; - /// Produce a capture block from an emulated event - /// \params[in] cb_id capture block identifier - std::vector produceCaptureBlockEvent(unsigned int cb_id) const; - /// Produce a ECON-D event from an emulated event - /// \param[in] econd_id ECON-D identifier - /// \param[in] cb_id capture block identifier - std::vector produceECONEvent(unsigned int econd_id, unsigned int cb_id = 0) const; - - /// Retrieve the last ECON-D event emulated - const econd::ECONDInput& lastECONDEmulatedInput() const { return last_emul_event_; } - /// Retrieve the metadata generated along with the last S-link emulated payload - const HGCalSlinkEmulatorInfo& lastSlinkEmulatedInfo() const { return last_slink_emul_info_; } - - /// List of S-link operational parameters for emulation - struct SlinkParameters { - std::vector active_econds{}; - unsigned int boe_marker{0}, eoe_marker{0}, format_version{0}, num_capture_blocks{1}; - bool store_header_trailer{true}; - }; - /// List of S-link operational parameters for emulation - const SlinkParameters& slinkParams() const { return slink_params_; } - /// List of ECON-D operational parameters for emulation - const std::map& econdParams() const { return econd_params_; } - - private: - econd::ERxChannelEnable generateEnabledChannels(unsigned int) const; - std::vector generateERxData(unsigned int, - const econd::ERxInput&, - std::vector&) const; - - static constexpr size_t kMaxNumECONDs = 12; - - struct HeaderBits { - bool bitO, bitB, bitE, bitT, bitH, bitS; - }; - HeaderBits generateStatusBits(unsigned int) const; - /// 32bit CRC - uint32_t computeCRC(const std::vector&) const; - - SlinkParameters slink_params_; - std::map econd_params_; - - CLHEP::HepRandomEngine* rng_{nullptr}; // NOT owning - mutable econd::Emulator* emul_{nullptr}; // NOT owning - - mutable HGCalSlinkEmulatorInfo last_slink_emul_info_; - mutable econd::ECONDInput last_emul_event_; - }; -} // namespace hgcal - -#endif diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h b/EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h deleted file mode 100644 index 59781271faf0b..0000000000000 --- a/EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Pedro Silva, CERN - * Laurent Forthomme, CERN - * - ****************************************************************************/ - -#ifndef EventFilter_HGCalRawToDigi_HGCalModuleTreeReader_h -#define EventFilter_HGCalRawToDigi_HGCalModuleTreeReader_h - -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h" - -namespace hgcal::econd { - /// Read out a the relevant raw data produced by a module to memory and returns ECON-D frames on request - /// \note The format is as agreed with system tests convenors so that it can be used in integration/beam tests - class HGCalModuleTreeReader : public Emulator { - public: - /// \param[in] tree_name Name of the TB events tree - /// \param[in] filenames List of filenames to loop on - /// \param[in] num_channels Channels multiplicity - explicit HGCalModuleTreeReader(const EmulatorParameters&, - const std::string& tree_name, - const std::vector& filenames); - - /// Input tree collections - struct HGCModuleTreeEvent { - unsigned int event, chip; - int half, bxcounter, eventcounter, orbitcounter, trigtime, trigwidth; - std::vector* daqdata{nullptr}; - }; - ECONDInput next() override; - - private: - ECONDInputColl data_; - ECONDInputColl::const_iterator it_data_; - }; - -} // namespace hgcal::econd - -#endif diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h b/EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h deleted file mode 100644 index 61f1427cae593..0000000000000 --- a/EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef EventFilter_HGCalRawToDigi_HGCalRawDataDefinitions_h -#define EventFilter_HGCalRawToDigi_HGCalRawDataDefinitions_h - -namespace hgcal { - namespace econd { - enum ToTStatus { ZeroSuppressed = 0x0, noZeroSuppressed_TOASuppressed = 0x1, invalid = 0x2, AutomaticFull = 0x3 }; - } - enum ECOND_FRAME { - HEADER_POS = 23, - HEADER_MASK = 0x1ff, - PAYLOAD_POS = 14, - PAYLOAD_MASK = 0x1ff, - BITP_POS = 13, - BITE_POS = 12, - HT_MASK = 0x3, - HT_POS = 10, - EBO_MASK = 0x3, - EBO_POS = 8, - BITM_POS = 7, - BITT_POS = 6, - EHHAM_MASK = 0x3f, - EHHAM_POS = 0, - BX_POS = 20, - BX_MASK = 0xfff, - L1A_POS = 14, - L1A_MASK = 0x3f, - ORBIT_POS = 11, - ORBIT_MASK = 0x7, - BITS_POS = 10, - RR_MASK = 0x3, - RR_POS = 8, - EHCRC_MASK = 0xff, - EHCRC_POS = 0, - ERXSTAT_POS = 29, - ERXSTAT_MASK = 0x7, - ERXHAM_POS = 26, - ERXHAM_MASK = 0x7, - ERXFORMAT_POS = 25, - ERXFORMAT_MASK = 0x1, - COMMONMODE0_POS = 15, - COMMONMODE0_MASK = 0x3ff, - COMMONMODE1_POS = 5, - COMMONMODE1_MASK = 0x3ff, - CHMAP32_POS = 0, - CHMAP32_MASK = 0x1f, - CHMAP0_POS = 0, - CHMAP0_MASK = 0xffffffff, - ERX_E_POS = 4, - ERX_E_MASK = 1 - }; - - enum BACKEND_FRAME { - CAPTUREBLOCK_RESERVED_MASK = 0x7f, - CAPTUREBLOCK_RESERVED_POS = 25, - CAPTUREBLOCK_BC_MASK = 0xfff, - CAPTUREBLOCK_BC_POS = 13, - CAPTUREBLOCK_EC_MASK = 0x7f, - CAPTUREBLOCK_EC_POS = 7, - CAPTUREBLOCK_OC_MASK = 0x7, - CAPTUREBLOCK_OC_POS = 4, - SLINK_BOE_MASK = 0xff, - SLINK_BOE_POS = 23, - SLINK_V_MASK = 0xf, - SLINK_V_POS = 19, - SLINK_R8_MASK = 0xff, - SLINK_R8_POS = 11, - SLINK_GLOBAL_EVENTID_MSB_MASK = 0xfff, - SLINK_GLOBAL_EVENTID_MSB_POS = 0, - SLINK_GLOBAL_EVENTID_LSB_MASK = 0xffffffff, - SLINK_GLOBAL_EVENTID_LSB_POS = 0, - SLINK_R6_MASK = 0x3f, - SLINK_R6_POS = 25, - SLINK_CONTENTID_MASK = 0x3FFFFFF, - SLINK_CONTENTID_POS = 0, - SLINK_SOURCEID_MASK = 0xffffffff, - SLINK_SOURCEID_POS = 0, - SLINK_EOE_MASK = 0xff, - SLINK_EOE_POS = 23, - SLINK_DAQCRC_MASK = 0xffff, - SLINK_DAQCRC_POS = 7, - SLINK_TRAILERR_MASK = 0xff, - SLINK_TRAILERR_POS = 0, - SLINK_EVLENGTH_MASK = 0xfffff, - SLINK_EVLENGTH_POS = 11, - SLINK_BXID_MASK = 0xfff, - SLINK_BXID_POS = 0, - SLINK_ORBID_MASK = 0xffffffff, - SLINK_ORBID_POS = 0, - SLINK_CRC_MASK = 0xffff, - SLINK_CRC_POS = 15, - SLINK_STATUS_MASK = 0xffff, - SLINK_STATUS_POS = 0, - }; -} // namespace hgcal - -#endif diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h b/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h index fccbc9de04c77..67a457f680a79 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h +++ b/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * This is a part of HGCAL offline software. + * Unpacker to decode HGCal raw data from SLinks * Authors: * Yulun Miao, Northwestern University * Huilin Qu, CERN @@ -11,132 +11,143 @@ #ifndef EventFilter_HGCalRawToDigi_HGCalUnpacker_h #define EventFilter_HGCalRawToDigi_HGCalUnpacker_h -#include "DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h" -#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" +#include "DataFormats/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "FWCore/Utilities/interface/Exception.h" #include #include #include -struct HGCalUnpackerConfig { - uint32_t sLinkBOE{0x0}; ///< S-Link BOE pattern - uint32_t captureBlockReserved{0x3f}; ///< Capture block reserved pattern - uint32_t econdHeaderMarker{0x154}; ///< ECON-D header Marker pattern - uint32_t sLinkCaptureBlockMax{10}; ///< maximum number of capture blocks in one S-Link - uint32_t captureBlockECONDMax{12}; ///< maximum number of ECON-Ds in one capture block - uint32_t econdERXMax{12}; ///< maximum number of eRxs in one ECON-D - uint32_t erxChannelMax{37}; ///< maximum number of channels in one eRx - uint32_t payloadLengthMax{469}; ///< maximum length of payload length - uint32_t channelMax{7000000}; ///< maximum number of channels unpacked - uint32_t commonModeMax{4000000}; ///< maximum number of common modes unpacked -}; - -/// This class is designed to unpack raw data from HGCal, formatted as S-Links, capture blocks, and ECON-Ds, to HGCROC channel data. -template class HGCalUnpacker { public: - enum SLinkHeaderShift { - kSLinkBOEShift = 24, - }; - enum SLinkHeaderMask { - kSLinkBOEMask = 0b11111111, - }; - enum CaptureBlockHeaderShift { - kCaptureBlockReservedShift = 26, - }; - enum CaptureBlockMask { - kCaptureBlockReservedMask = 0b111111, - kCaptureBlockECONDStatusMask = 0b111, - }; - enum ECONDHeaderShift { - kHeaderShift = 23, - kPayloadLengthShift = 14, - kPassThroughShift = 13, - kHTShift = 10, - kEBOShift = 8, - kMatchShift = 7, - kTruncatedShift = 6, - }; - enum ECONDHeaderMask { - kHeaderMask = 0b111111111, - kPayloadLengthMask = 0b111111111, - kPassThroughMask = 0b1, - kHTMask = 0b11, - kEBOMask = 0b11, - kMatchMask = 0b1, - kTruncatedMask = 0b1, - }; - enum ERXHeaderShift { - kFormatShift = 25, - kCommonmode0Shift = 15, - kCommonmode1Shift = 5, - }; - enum ERXHeaderMask { - kFormatMask = 0b1, - kCommonmode0Mask = 0b1111111111, - kCommonmode1Mask = 0b1111111111, - }; + HGCalUnpacker() {} - explicit HGCalUnpacker(HGCalUnpackerConfig config); + // TODO @hqucms + // define what is needed as `config` + // HGCalUnpacker(HGCalUnpackerConfig config); - /// parse input in S-Link format - /// \param[in] inputArray input as 32-bits words vector. - /// \param[in] enabledERXMapping map from S-Link indices to enabled eRx in this ECON-D - /// \param[in] logicalMapping logical mapping from HGCalElectronicsId to class D as ID - void parseSLink(const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping); - /// parse input in capture block format - /// \param[in] inputArray input as 32-bits words vector. - /// \param[in] enabledERXMapping map from capture block indices to enabled eRx in this ECON-D - /// \param[in] logicalMapping logical mapping from HGCalElectronicsId to class D as ID - void parseCaptureBlock( - const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping); - /// parse input in ECON-D format - /// \param[in] inputArray input as 32-bits words vector. - /// \param[in] enabledERXMapping map from ECON-D indices to enabled eRx in this ECON-D - /// \param[in] logicalMapping logical mapping from HGCalElectronicsId to class D as ID - void parseECOND(const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping); - - /// \return vector of HGCROCChannelDataFrame(ID, value) - const std::vector >& channelData() const { return channelData_; } - /// \return vector of 32-bit index, the length is the same as channelData(), link from channel data to the first common mode on ROC (+0,+1,+2,+3 for all four common modes) - const std::vector& commonModeIndex() const { return commonModeIndex_; } - /// \return vector of 16-bit common mode data, lowest 10 bits is the ADC of the common mode, padding to 4 for half ROC turned on - const std::vector& commonModeData() const { return commonModeData_; } - const std::vector& badECOND() const { return badECOND_; } + uint8_t parseFEDData(unsigned fedId, + const FEDRawData& fed_data, + const HGCalMappingModuleIndexer& moduleIndexer, + const HGCalConfiguration& config, + hgcaldigi::HGCalDigiHost& digis, + hgcaldigi::HGCalECONDPacketInfoHost& econdPacketInfo, + bool headerOnlyMode = false); private: - const uint32_t erxBodyLeftShift_[16] = {2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - const uint32_t erxBodyRightShift_[16] = {0, 8, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - const uint32_t erxBodyMask_[16] = {0b00111111111111111111110000000000, - 0b00000000000011111111110000000000, - 0b00111111111111111111110000000000, - 0b00000000000011111111111111111111, - 0b00111111111111111111111111111111, - 0b00111111111111111111111111111111, - 0b00111111111111111111111111111111, - 0b00111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111, - 0b11111111111111111111111111111111}; - const uint32_t erxBodyBits_[16] = {24, 16, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}; - HGCalUnpackerConfig config_; - size_t channelDataSize_{0}; ///< Size of unpacked channels - size_t commonModeDataSize_{0}; ///< Size of unpacked common modes - std::vector > channelData_; ///< Array for unpacked channels - std::vector commonModeIndex_; ///< Array for logicalMapping between unpacked channels to first common mode - std::vector commonModeData_; ///< Array for unpacked common modes - std::vector badECOND_; ///< Array of indices of bad ECON-Ds + constexpr static uint8_t tctp_[16] = { + 0b00, 0b00, 0b01, 0b00, 0b00, 0b00, 0b00, 0b00, 0b10, 0b10, 0b10, 0b10, 0b11, 0b11, 0b11, 0b11}; + + constexpr static uint32_t adcm1Mask_[16] = {0b1111111111, + 0b0000000000, + 0b1111111111, + 0b0000000000, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111}; + constexpr static uint32_t adcm1Shift_[16] = { + 18, + 28, + 18, + 0, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + }; + + constexpr static uint32_t adcShift_[16] = {8, 18, 8, 18, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0}; + constexpr static uint32_t adcMask_[16] = {0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000}; + + constexpr static uint32_t totShift_[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10}; + constexpr static uint32_t totMask_[16] = {0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b0000000000, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111}; + + constexpr static uint32_t toaShift_[16] = {0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + constexpr static uint32_t toaMask_[16] = {0b0000000000, + 0b0000000000, + 0b0000000000, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111, + 0b1111111111}; + constexpr static uint16_t flags_[16] = {hgcal::DIGI_FLAG::ZS_ToA, + hgcal::DIGI_FLAG::ZS_ToA_ADCm1, + hgcal::DIGI_FLAG::ZS_ToA, + hgcal::DIGI_FLAG::ZS_ADCm1, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::Invalid, + hgcal::DIGI_FLAG::Invalid, + hgcal::DIGI_FLAG::Invalid, + hgcal::DIGI_FLAG::Invalid, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT, + hgcal::DIGI_FLAG::FULL_READOUT}; + constexpr static uint32_t erxBodyBits_[16] = {24, 16, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}; }; #endif diff --git a/EventFilter/HGCalRawToDigi/plugins/BuildFile.xml b/EventFilter/HGCalRawToDigi/plugins/BuildFile.xml index 56064bfb8f6e3..fadf379791ddc 100644 --- a/EventFilter/HGCalRawToDigi/plugins/BuildFile.xml +++ b/EventFilter/HGCalRawToDigi/plugins/BuildFile.xml @@ -1,8 +1,6 @@ - - diff --git a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc index 1d99435a81b61..8bae2a91cf699 100644 --- a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc +++ b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc @@ -4,15 +4,26 @@ #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/ESWatcher.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/StreamID.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h" - #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h" #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" -#include "DataFormats/HGCalDigi/interface/HGCalDigiCollections.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" + +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "oneapi/tbb/task_arena.h" +#include "oneapi/tbb.h" + +#include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h" class HGCalRawToDigi : public edm::stream::EDProducer<> { public: explicit HGCalRawToDigi(const edm::ParameterSet&); @@ -21,108 +32,113 @@ class HGCalRawToDigi : public edm::stream::EDProducer<> { private: void produce(edm::Event&, const edm::EventSetup&) override; + void beginRun(edm::Run const&, edm::EventSetup const&) override; + // input tokens const edm::EDGetTokenT fedRawToken_; - const edm::EDPutTokenT digisToken_; - const edm::EDPutTokenT elecDigisToken_; - const std::vector fedIds_; - const unsigned int badECONDMax_; - const unsigned int numERxsInECOND_; - const std::unique_ptr > unpacker_; + // output tokens + const edm::EDPutTokenT digisToken_; + const edm::EDPutTokenT econdPacketInfoToken_; + + // TODO @hqucms + // what else do we want to output? + + // config tokens and objects + edm::ESWatcher mapWatcher_; + edm::ESGetToken cellIndexToken_; + edm::ESGetToken moduleIndexToken_; + edm::ESGetToken configToken_; + HGCalMappingCellIndexer cellIndexer_; + HGCalMappingModuleIndexer moduleIndexer_; + HGCalConfiguration config_; + + // TODO @hqucms + // how to implement this enabled eRx pattern? Can this be taken from the logical mapping? + // HGCalCondSerializableModuleInfo::ERxBitPatternMap erxEnableBits_; + // std::map fed2slink_; + + // TODO @hqucms + // HGCalUnpackerConfig unpackerConfig_; + HGCalUnpacker unpacker_; + + const bool fixCalibChannel_; }; HGCalRawToDigi::HGCalRawToDigi(const edm::ParameterSet& iConfig) : fedRawToken_(consumes(iConfig.getParameter("src"))), - digisToken_(produces()), - elecDigisToken_(produces()), - fedIds_(iConfig.getParameter >("fedIds")), - badECONDMax_(iConfig.getParameter("badECONDMax")), - numERxsInECOND_(iConfig.getParameter("numERxsInECOND")), - unpacker_(new HGCalUnpacker( - HGCalUnpackerConfig{.sLinkBOE = iConfig.getParameter("slinkBOE"), - .captureBlockReserved = iConfig.getParameter("captureBlockReserved"), - .econdHeaderMarker = iConfig.getParameter("econdHeaderMarker"), - .sLinkCaptureBlockMax = iConfig.getParameter("maxCaptureBlock"), - .captureBlockECONDMax = iConfig.getParameter("captureBlockECONDMax"), - .econdERXMax = iConfig.getParameter("econdERXMax"), - .erxChannelMax = iConfig.getParameter("erxChannelMax"), - .payloadLengthMax = iConfig.getParameter("payloadLengthMax"), - .channelMax = iConfig.getParameter("channelMax"), - .commonModeMax = iConfig.getParameter("commonModeMax")})) {} + digisToken_(produces()), + econdPacketInfoToken_(produces()), + cellIndexToken_(esConsumes()), + moduleIndexToken_(esConsumes()), + configToken_(esConsumes()), + // unpackerConfig_(HGCalUnpackerConfig{.sLinkBOE = iConfig.getParameter("slinkBOE"), + // .cbHeaderMarker = iConfig.getParameter("cbHeaderMarker"), + // .econdHeaderMarker = iConfig.getParameter("econdHeaderMarker"), + // .payloadLengthMax = iConfig.getParameter("payloadLengthMax"), + // .applyFWworkaround = iConfig.getParameter("applyFWworkaround")}), + fixCalibChannel_(iConfig.getParameter("fixCalibChannel")) {} + +void HGCalRawToDigi::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) { + // retrieve logical mapping + if (mapWatcher_.check(iSetup)) { + moduleIndexer_ = iSetup.getData(moduleIndexToken_); + cellIndexer_ = iSetup.getData(cellIndexToken_); + config_ = iSetup.getData(configToken_); + } + + // TODO @hqucms + // retrieve configs: TODO + // auto moduleInfo = iSetup.getData(moduleInfoToken_); + + // TODO @hqucms + // init unpacker with proper configs +} void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + hgcaldigi::HGCalDigiHost digis(moduleIndexer_.getMaxDataSize(), cms::alpakatools::host()); + hgcaldigi::HGCalECONDPacketInfoHost econdPacketInfo(moduleIndexer_.getMaxModuleSize(), cms::alpakatools::host()); + // std::cout << "Created DIGIs SOA with " << digis.view().metadata().size() << " entries" << std::endl; + + // TODO @hqucms + // retrieve the FED raw data const auto& raw_data = iEvent.get(fedRawToken_); - // prepare the output - HGCalDigiCollection digis; - HGCalElecDigiCollection elec_digis; - for (const auto& fed_id : fedIds_) { - const auto& fed_data = raw_data.FEDData(fed_id); - if (fed_data.size() == 0) - continue; - - std::vector data_32bit; - auto* ptr = fed_data.data(); - size_t fed_size = fed_data.size(); - for (size_t i = 0; i < fed_size; i += 4) - data_32bit.emplace_back(((*(ptr + i) & 0xff) << 0) + (((i + 1) < fed_size) ? ((*(ptr + i + 1) & 0xff) << 8) : 0) + - (((i + 2) < fed_size) ? ((*(ptr + i + 2) & 0xff) << 16) : 0) + - (((i + 3) < fed_size) ? ((*(ptr + i + 3) & 0xff) << 24) : 0)); - - unpacker_->parseSLink( - data_32bit, - [this](uint16_t /*sLink*/, uint8_t /*captureBlock*/, uint8_t /*econd*/) { return (1 << numERxsInECOND_) - 1; }, - [](HGCalElectronicsId elecID) -> HGCalElectronicsId { return elecID; }); - const auto elecid_to_detid = [](const HGCalElectronicsId& id) -> HGCalDetId { - return HGCalDetId(id.raw()); - }; //TODO: implement something more relevant - - auto channeldata = unpacker_->channelData(); - auto cms = unpacker_->commonModeIndex(); - for (unsigned int i = 0; i < channeldata.size(); i++) { - auto data = channeldata.at(i); - auto cm = cms.at(i); - const auto& id = data.id(); - auto idraw = id.raw(); - auto raw = data.raw(); - LogDebug("HGCalRawToDigi:produce") << "id=" << idraw << ", raw=" << raw << ", common mode index=" << cm << "."; - digis.push_back(HGCROCChannelDataFrameSpec(elecid_to_detid(id), data.raw())); - elec_digis.push_back(data); - } - if (const auto& bad_econds = unpacker_->badECOND(); !bad_econds.empty()) { - if (bad_econds.size() > badECONDMax_) - throw cms::Exception("HGCalRawToDigi:produce") - << "Too many bad ECON-Ds: " << bad_econds.size() << " > " << badECONDMax_ << "."; - edm::LogWarning("HGCalRawToDigi:produce").log([&bad_econds](auto& log) { - log << "Bad ECON-D: " << std::dec; - std::string prefix; - for (const auto& badECOND : bad_econds) - log << prefix << badECOND, prefix = ", "; - log << "."; - }); - } + + for (int32_t i = 0; i < digis.view().metadata().size(); i++) { + digis.view()[i].flags() = hgcal::DIGI_FLAG::NotAvailable; } + // TODO: comparing timing of multithread and FED-level parrallelization + // for (unsigned fedId = 0; fedId < moduleIndexer_.nfeds_; ++fedId) { + // const auto& fed_data = raw_data.FEDData(fedId); + // if (fed_data.size() == 0) + // continue; + // unpacker_.parseFEDData(fedId, fed_data, moduleIndexer_, config_, digis, econdPacketInfo, /*headerOnlyMode*/ false); + // } + + //Parallelization + tbb::this_task_arena::isolate([&]() { + tbb::parallel_for(0U, moduleIndexer_.nfeds_, [&](unsigned fedId) { + const auto& fed_data = raw_data.FEDData(fedId); + if (fed_data.size() == 0) + return; + unpacker_.parseFEDData( + fedId, fed_data, moduleIndexer_, config_, digis, econdPacketInfo, /*headerOnlyMode*/ false); + return; + }); + }); + // put information to the event iEvent.emplace(digisToken_, std::move(digis)); - iEvent.emplace(elecDigisToken_, std::move(elec_digis)); + iEvent.emplace(econdPacketInfoToken_, std::move(econdPacketInfo)); } +// fill descriptions void HGCalRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("src", edm::InputTag("rawDataCollector")); - desc.add("maxCaptureBlock", 1)->setComment("maximum number of capture blocks in one S-Link"); - desc.add("captureBlockReserved", 0)->setComment("capture block reserved pattern"); - desc.add("econdHeaderMarker", 0x154)->setComment("ECON-D header Marker pattern"); - desc.add("slinkBOE", 0x2a)->setComment("SLink BOE pattern"); - desc.add("captureBlockECONDMax", 12)->setComment("maximum number of ECON-D's in one capture block"); - desc.add("econdERXMax", 12)->setComment("maximum number of eRx's in one ECON-D"); - desc.add("erxChannelMax", 37)->setComment("maximum number of channels in one eRx"); - desc.add("payloadLengthMax", 469)->setComment("maximum length of payload length"); - desc.add("channelMax", 7000000)->setComment("maximum number of channels unpacked"); - desc.add("commonModeMax", 4000000)->setComment("maximum number of common modes unpacked"); - desc.add("badECONDMax", 200)->setComment("maximum number of bad ECON-D's"); desc.add >("fedIds", {}); - desc.add("numERxsInECOND", 12)->setComment("number of eRxs in each ECON-D payload"); + desc.add("fixCalibChannel", true) + ->setComment("FIXME: always treat calib channels in characterization mode; to be fixed in ROCv3b"); descriptions.add("hgcalDigis", desc); } diff --git a/EventFilter/HGCalRawToDigi/plugins/HGCalSlinkEmulator.cc b/EventFilter/HGCalRawToDigi/plugins/HGCalSlinkEmulator.cc deleted file mode 100644 index c56c405d7dbfb..0000000000000 --- a/EventFilter/HGCalRawToDigi/plugins/HGCalSlinkEmulator.cc +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Pedro Silva, CERN - * Laurent Forthomme, CERN - * - ****************************************************************************/ - -#include - -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/EmptyGroupDescription.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/Utilities/interface/CRC16.h" -#include "FWCore/Utilities/interface/RandomNumberGenerator.h" -#include "FWCore/Utilities/interface/StreamID.h" - -#include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h" -#include "DataFormats/FEDRawData/interface/FEDHeader.h" -#include "DataFormats/FEDRawData/interface/FEDTrailer.h" - -#include "DataFormats/HGCalDigi/interface/HGCalRawDataEmulatorInfo.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h" - -class HGCalSlinkEmulator : public edm::stream::EDProducer<> { -public: - explicit HGCalSlinkEmulator(const edm::ParameterSet&); - - static void fillDescriptions(edm::ConfigurationDescriptions&); - -private: - void produce(edm::Event&, const edm::EventSetup&) override; - - const unsigned int fed_id_; - - const bool store_emul_info_; - const bool store_fed_header_trailer_; - - const edm::EDPutTokenT fedRawToken_; - std::unique_ptr emulator_; - - edm::Service rng_; - edm::EDPutTokenT fedEmulInfoToken_; - hgcal::HGCalFrameGenerator frame_gen_; -}; - -HGCalSlinkEmulator::HGCalSlinkEmulator(const edm::ParameterSet& iConfig) - : fed_id_(iConfig.getParameter("fedId")), - store_emul_info_(iConfig.getParameter("storeEmulatorInfo")), - store_fed_header_trailer_(iConfig.getParameter("fedHeaderTrailer")), - fedRawToken_(produces()), - frame_gen_(iConfig) { - // figure out which emulator is to be used - const auto& emul_type = iConfig.getParameter("emulatorType"); - if (frame_gen_.econdParams().empty()) - throw cms::Exception("HGCalSlinkEmulator") - << "No ECON-D parameters were retrieved from the configuration. Please add at least one."; - const auto& econd_params = frame_gen_.econdParams().begin()->second; - if (emul_type == "trivial") - emulator_ = std::make_unique(econd_params); - else if (emul_type == "hgcmodule") - emulator_ = std::make_unique( - econd_params, - iConfig.getUntrackedParameter("treeName"), - iConfig.getUntrackedParameter>("inputs")); - else - throw cms::Exception("HGCalSlinkEmulator") << "Invalid emulator type chosen: '" << emul_type << "'."; - - frame_gen_.setEmulator(*emulator_); - - // ensure the random number generator service is present in configuration - if (!rng_.isAvailable()) - throw cms::Exception("HGCalSlinkEmulator") << "The HGCalSlinkEmulator module requires the " - "RandomNumberGeneratorService,\n" - "which appears to be absent. Please add that service to your " - "configuration\n" - "or remove the modules that require it."; - - if (store_emul_info_) - fedEmulInfoToken_ = produces(); -} - -void HGCalSlinkEmulator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - frame_gen_.setRandomEngine(rng_->getEngine(iEvent.streamID())); - - // build the S-link payload - auto slink_event = frame_gen_.produceSlinkEvent(fed_id_); - const auto slink_event_size = slink_event.size() * sizeof(slink_event.at(0)); - - // compute the total S-link payload size - size_t total_event_size = slink_event_size; - if (store_fed_header_trailer_) - total_event_size += FEDHeader::length + FEDTrailer::length; - - // fill the output FED raw data collection - FEDRawDataCollection raw_data; - auto& fed_data = raw_data.FEDData(fed_id_); - fed_data.resize(total_event_size); - auto* ptr = fed_data.data(); - - if (store_fed_header_trailer_) { - const auto& last_event = frame_gen_.lastECONDEmulatedInput(); - const auto event_id = std::get<0>(last_event.first), bx_id = std::get<1>(last_event.first); - int trg_type = 0; - // compose 2*32-bit FED header word - FEDHeader::set(ptr, trg_type, event_id, bx_id, fed_id_); - LogDebug("HGCalSlinkEmulator").log([&](auto& log) { - const FEDHeader hdr(ptr); - log << "FED header: lvl1ID=" << hdr.lvl1ID() << ", bxID=" << hdr.bxID() << ", source ID=" << hdr.sourceID() - << "."; - }); - ptr += FEDHeader::length; - } - - // insert ECON-D payload - std::memcpy(ptr, slink_event.data(), slink_event_size); - ptr += slink_event_size; - LogDebug("HGCalSlinkEmulator") << "Wrote " << slink_event.size() << " 64-bit words = " << slink_event_size - << " 8-bit words."; - - if (store_fed_header_trailer_) { - // compose 2*32-bit FED trailer word - FEDTrailer::set(ptr, - slink_event.size() + 2, - evf::compute_crc(reinterpret_cast(slink_event.data()), slink_event_size), - 0, - 0); - LogDebug("HGCalSlinkEmulator").log([&](auto& log) { - const FEDTrailer trl(ptr); - log << "FED trailer: fragment length: " << trl.fragmentLength() << ", CRC=0x" << std::hex << trl.crc() << std::dec - << ", status: " << trl.evtStatus() << "."; - }); - ptr += FEDTrailer::length; - } - - iEvent.emplace(fedRawToken_, std::move(raw_data)); - - // store the emulation information if requested - if (store_emul_info_) - iEvent.emplace(fedEmulInfoToken_, frame_gen_.lastSlinkEmulatedInfo()); -} - -// -void HGCalSlinkEmulator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - auto desc = hgcal::HGCalFrameGenerator::description(); - desc.ifValue( - edm::ParameterDescription("emulatorType", "trivial", true), - // trivial emulator - "trivial" >> edm::EmptyGroupDescription() or - // test beam tree content - "hgcmodule" >> (edm::ParameterDescription("treeName", "hgcroc_rawdata/eventdata", false) and - edm::ParameterDescription>("inputs", {}, false))) - ->setComment("emulator mode (trivial, or hgcmodule)"); - desc.add("fedId", 0)->setComment("FED number delivering the emulated frames"); - desc.add("fedHeaderTrailer", false)->setComment("also add FED header/trailer info"); - desc.add("storeEmulatorInfo", false) - ->setComment("also append a 'truth' auxiliary info to the output event content"); - descriptions.add("hgcalEmulatedSlinkRawData", desc); -} - -// define this as a plug-in -DEFINE_FWK_MODULE(HGCalSlinkEmulator); diff --git a/EventFilter/HGCalRawToDigi/src/HGCalFrameGenerator.cc b/EventFilter/HGCalRawToDigi/src/HGCalFrameGenerator.cc deleted file mode 100644 index 8fb44cf495294..0000000000000 --- a/EventFilter/HGCalRawToDigi/src/HGCalFrameGenerator.cc +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Laurent Forthomme, CERN - * - ****************************************************************************/ - -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/CRC16.h" - -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataPackingTools.h" - -#include "CLHEP/Random/RandFlat.h" -#include - -namespace hgcal { - //-------------------------------------------------- - // bit-casting utilities - //-------------------------------------------------- - - template - void printWords(edm::MessageSender& os, const std::string& name, const std::vector vec) { - os << "Dump of the '" << name << "' words:\n"; - for (size_t i = 0; i < vec.size(); ++i) - os << std::dec << std::setfill(' ') << std::setw(4) << i << ": 0x" << std::hex << std::setfill('0') - << std::setw(sizeof(T) * 2) << vec.at(i) << "\n"; - } - - static std::vector to64bit(const std::vector& in) { - std::vector out; - for (size_t i = 0; i < in.size(); i += 2) { - uint64_t word1 = (i < in.size()) ? in.at(i) : 0ul, word2 = (i + 1 < in.size()) ? in.at(i + 1) : 0ul; - out.emplace_back(((word2 & 0xffffffff) << 32) | (word1 & 0xffffffff)); - } - return out; - } - - static std::vector to128bit(const std::vector& in) { - std::vector out; - for (size_t i = 0; i < in.size(); i += 2) { - out.emplace_back(in.at(i)); - out.emplace_back((i + 1 < in.size()) ? in.at(i + 1) : 0u); - } - return out; - } - - HGCalFrameGenerator::HGCalFrameGenerator(const edm::ParameterSet& iConfig) { - const auto slink_config = iConfig.getParameter("slinkParams"); - - size_t econd_id = 0; - std::vector active_econds; - for (const auto& econd : slink_config.getParameter >("ECONDs")) { - // a bit of user input validation - if (slink_config.getParameter("checkECONDsLimits")) { - if (active_econds.size() > kMaxNumECONDs) - throw cms::Exception("HGCalFrameGenerator") - << "Too many active ECON-D set: " << active_econds.size() << " > " << kMaxNumECONDs << "."; - if (econd_id >= kMaxNumECONDs) - throw cms::Exception("HGCalFrameGenerator") - << "Invalid ECON-D identifier: " << econd_id << " >= " << kMaxNumECONDs << "."; - } - if (econd.getParameter("active")) - active_econds.emplace_back(econd_id); - - econd_params_.insert(std::make_pair(econd_id, econd::EmulatorParameters(econd))); - ++econd_id; - } - - slink_params_ = SlinkParameters{.active_econds = active_econds, - .boe_marker = slink_config.getParameter("boeMarker"), - .eoe_marker = slink_config.getParameter("eoeMarker"), - .format_version = slink_config.getParameter("formatVersion"), - .num_capture_blocks = slink_config.getParameter("numCaptureBlocks"), - .store_header_trailer = slink_config.getParameter("storeHeaderTrailer")}; - } - - edm::ParameterSetDescription HGCalFrameGenerator::description() { - edm::ParameterSetDescription desc; - - std::vector econds_psets; - for (size_t i = 0; i < 7; ++i) - econds_psets.emplace_back(); - - edm::ParameterSetDescription slink_desc; - slink_desc.addVPSet("ECONDs", econd::EmulatorParameters::description(), econds_psets) - ->setComment("list of active ECON-Ds in S-link"); - slink_desc.add("boeMarker", 0x55); - slink_desc.add("eoeMarker", 0xaa); - slink_desc.add("formatVersion", 3); - slink_desc.add("numCaptureBlocks", 1) - ->setComment("number of capture blocks to emulate per S-link payload"); - slink_desc.add("checkECONDsLimits", true)->setComment("check the maximal number of ECON-Ds per S-link"); - slink_desc.add("storeHeaderTrailer", true)->setComment("also store the S-link header and trailer words"); - desc.add("slinkParams", slink_desc); - - return desc; - } - - void HGCalFrameGenerator::setRandomEngine(CLHEP::HepRandomEngine& rng) { rng_ = &rng; } - - void HGCalFrameGenerator::setEmulator(econd::Emulator& emul) { emul_ = &emul; } - - //-------------------------------------------------- - // emulation part - //-------------------------------------------------- - - HGCalFrameGenerator::HeaderBits HGCalFrameGenerator::generateStatusBits(unsigned int econd_id) const { - if (!rng_) - throw cms::Exception("HGCalFrameGenerator") << "Random number generator not initialised."; - const auto& econd_params = econd_params_.at(econd_id); - // first sample on header status bits - return HeaderBits{ - .bitO = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitO, - .bitB = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitB, - .bitE = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitE, - .bitT = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitT, - .bitH = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitH, - .bitS = CLHEP::RandFlat::shoot(rng_) < econd_params.error_prob.bitS, - }; - } - - econd::ERxChannelEnable HGCalFrameGenerator::generateEnabledChannels(unsigned int econd_id) const { - const auto& econd_params = econd_params_.at(econd_id); - econd::ERxChannelEnable chmap(econd_params.num_channels_per_erx, false); - for (size_t i = 0; i < chmap.size(); i++) - // randomly choosing the channels to be shot at - chmap[i] = CLHEP::RandFlat::shoot(rng_) <= econd_params.chan_surv_prob; - return chmap; - } - - std::vector HGCalFrameGenerator::generateERxData( - unsigned int econd_id, - const econd::ERxInput& input_event, - std::vector& enabled_channels) const { - const auto& econd_params = econd_params_.at(econd_id); - std::vector erx_data; - enabled_channels.clear(); - for (const auto& jt : input_event) { // one per eRx - const auto chmap = - generateEnabledChannels(econd_id); // generate a list of probable channels to be filled with emulated content - - // insert eRx header (common mode, channels map, ...) - uint8_t stat = 0b111 /*possibly emulate*/, hamming_check = 0; - bool bit_e = false; // did unmasked stat error bits associated with the eRx cause the sub-packet to be supressed? - auto erx_header = econd::eRxSubPacketHeader(stat, hamming_check, bit_e, jt.second.cm0, jt.second.cm1, chmap); - erx_data.insert(erx_data.end(), erx_header.begin(), erx_header.end()); - if (jt.second.adc.size() < econd_params.num_channels_per_erx) { - edm::LogError("HGCalFrameGenerator:generateERxData") - << "Data multiplicity too low (" << jt.second.adc.size() << ") to emulate " - << econd_params.num_channels_per_erx << " ECON-D channel(s)."; - continue; - } - // insert eRx payloads (integrating all readout channels) - const auto erx_chan_data = econd::produceERxData(chmap, - jt.second, - true, // passZS - true, // passZSm1 - true, // hasToA - econd_params.characterisation_mode); - erx_data.insert(erx_data.end(), erx_chan_data.begin(), erx_chan_data.end()); - enabled_channels.emplace_back(chmap); - } - LogDebug("HGCalFrameGenerator").log([&erx_data](auto& log) { printWords(log, "erx", erx_data); }); - return erx_data; - } - - uint32_t HGCalFrameGenerator::computeCRC(const std::vector& event_header) const { - uint32_t crc = 0x12345678; //TODO: implement 32-bit Bluetooth CRC in the future - return crc; - } - - //-------------------------------------------------- - // payload creation utilities - //-------------------------------------------------- - - std::vector HGCalFrameGenerator::produceECONEvent(unsigned int econd_id, unsigned int cb_id) const { - if (!emul_) - throw cms::Exception("HGCalFrameGenerator") - << "ECON-D emulator was not properly set to the frame generator. Please ensure you are calling the " - "HGCalFrameGenerator::setEmulator method."; - - std::vector econd_event; - - const auto event = emul_->next(); - const auto& econd_params = econd_params_.at(econd_id); - auto header_bits = generateStatusBits(econd_id); - std::vector enabled_ch_per_erx; - auto erx_payload = generateERxData(econd_id, event.second, enabled_ch_per_erx); - - // ECON-D event content was just created, now prepend packet header - const uint8_t hamming = 0, rr = 0; - auto econd_header = - econd::eventPacketHeader(econd_params.header_marker, - erx_payload.size() + 1 /*CRC*/, - econd_params.passthrough_mode, - econd_params.expected_mode, - // HGCROC Event reco status across all active eRx E-B-O: - (header_bits.bitH & 0x1) << 1 | (header_bits.bitT & 0x1), // HDR/TRL numbers - (header_bits.bitE & 0x1) << 2 | (header_bits.bitB & 0x1) << 1 | - (header_bits.bitO & 0x1), // Event/BX/Orbit numbers - econd_params.matching_ebo_numbers, - econd_params.bo_truncated, - hamming, // Hamming for event header - std::get<1>(event.first), // BX - std::get<0>(event.first), // event id (L1A) - std::get<2>(event.first), // orbit - header_bits.bitS, // OR of "Stat" bits for all active eRx - rr); - LogDebug("HGCalFrameGenerator").log([&econd_header](auto& log) { printWords(log, "econ-d header", econd_header); }); - auto econd_header_64bit = to64bit(econd_header); - econd_event.insert(econd_event.end(), econd_header_64bit.begin(), econd_header_64bit.end()); - LogDebug("HGCalFrameGenerator") << econd_header.size() - << " word(s) of event packet header prepend. New size of ECON frame: " - << econd_event.size(); - const auto erx_payload_64bit = to64bit(erx_payload); - econd_event.insert(econd_event.end(), erx_payload_64bit.begin(), erx_payload_64bit.end()); - LogDebug("HGCalFrameGenerator") << erx_payload.size() << " word(s) of eRx payloads inserted."; - - std::vector econd_footer; - if (econd_params.add_econd_crc) - econd_footer.emplace_back(computeCRC(econd_header)); - if (econd_params.add_idle_word) { - const uint8_t buffer_status = 0, error_status = 0, reset_request = 0; - econd_footer.emplace_back( - econd::buildIdleWord(buffer_status, error_status, reset_request, econd_params.programmable_pattern)); - } - econd_event.insert(econd_event.end(), econd_footer.begin(), econd_footer.end()); - // bookkeeping of last event + metadata - last_slink_emul_info_.captureBlockEmulatedInfo(cb_id).addECONDEmulatedInfo( - econd_id, - HGCalECONDEmulatorInfo(header_bits.bitO, - header_bits.bitT, - header_bits.bitE, - header_bits.bitT, - header_bits.bitH, - header_bits.bitS, - enabled_ch_per_erx)); - last_emul_event_ = event; - return econd_event; - } - - std::vector HGCalFrameGenerator::produceCaptureBlockEvent(unsigned int cb_id) const { - std::vector cb_event; - // build all ECON-Ds payloads and add them to the capture block payload - std::vector econd_statuses(kMaxNumECONDs, backend::ECONDPacketStatus::InactiveECOND); - for (const auto& econd : econd_params_) { // for each ECON-D payload to be emulated - const auto& econd_id = econd.first; - if (!econd.second.active) - continue; // status is already inactive - econd_statuses[econd_id] = - backend::ECONDPacketStatus::Normal; //TODO: also implement/emulate other ECON-D packet issues - const auto econd_payload = produceECONEvent(econd_id, cb_id); - cb_event.insert(cb_event.end(), econd_payload.begin(), econd_payload.end()); - } - const auto& eid = last_emul_event_.first; - const uint64_t event_id = std::get<0>(eid), bx_id = std::get<1>(eid), orbit_id = std::get<2>(eid); - // prepend the header to the capture block payload - const auto l1a_header = to64bit(backend::buildCaptureBlockHeader(bx_id, event_id, orbit_id, econd_statuses)); - LogDebug("HGCalFrameGenerator").log([&l1a_header](auto& log) { printWords(log, "l1a", l1a_header); }); - cb_event.insert(cb_event.begin(), l1a_header.begin(), l1a_header.end()); - return to128bit(cb_event); - } - - std::vector HGCalFrameGenerator::produceSlinkEvent(unsigned int fed_id) const { - last_slink_emul_info_.clear(); // clear the metadata of the latest emulated S-link payload - - std::vector slink_event; // prepare the output S-link payload (will be "converted" to 128-bit) - for (unsigned int cb_id = 0; cb_id < slink_params_.num_capture_blocks; ++cb_id) { - const auto cb_payload = produceCaptureBlockEvent(cb_id); - slink_event.insert(slink_event.end(), - cb_payload.begin(), - cb_payload.end()); // concatenate the capture block to the full S-link payload - } - - if (slink_params_.store_header_trailer) { - // build the S-link header words - const uint32_t content_id = backend::buildSlinkContentId(backend::SlinkEmulationFlag::Subsystem, 0, 0); - const auto& eid = last_emul_event_.first; - const uint64_t event_id = std::get<0>(eid), bx_id = std::get<1>(eid), orbit_id = std::get<2>(eid); - const auto slink_header = to128bit(to64bit(backend::buildSlinkHeader( - slink_params_.boe_marker, slink_params_.format_version, event_id, content_id, fed_id))); - slink_event.insert(slink_event.begin(), slink_header.begin(), slink_header.end()); // prepend S-link header - - // build the S-link trailer words - const bool fed_crc_err = false, slinkrocket_crc_err = false, source_id_err = false, sync_lost = false, - fragment_trunc = false; - const uint16_t status = - backend::buildSlinkRocketStatus(fed_crc_err, slinkrocket_crc_err, source_id_err, sync_lost, fragment_trunc); - - const uint16_t daq_crc = 0, crc = 0; - const uint32_t event_length = slink_event.size() - slink_header.size() - 1; - const auto slink_trailer = to128bit(to64bit( - backend::buildSlinkTrailer(slink_params_.eoe_marker, daq_crc, event_length, bx_id, orbit_id, crc, status))); - slink_event.insert(slink_event.end(), slink_trailer.begin(), slink_trailer.end()); // append S-link trailer - - LogDebug("HGCalFrameGenerator").log([&slink_header, &slink_trailer](auto& log) { - printWords(log, "slink header", slink_header); - log << "\n"; - printWords(log, "slink trailer", slink_trailer); - }); - } - - return to128bit(slink_event); - } -} // namespace hgcal diff --git a/EventFilter/HGCalRawToDigi/src/HGCalModuleTreeReader.cc b/EventFilter/HGCalRawToDigi/src/HGCalModuleTreeReader.cc deleted file mode 100644 index 90e79246868a8..0000000000000 --- a/EventFilter/HGCalRawToDigi/src/HGCalModuleTreeReader.cc +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Pedro Silva, CERN - * Laurent Forthomme, CERN - * - ****************************************************************************/ - -#include "DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/Exception.h" - -#include "TChain.h" - -using namespace hgcal::econd; - -HGCalModuleTreeReader::HGCalModuleTreeReader(const EmulatorParameters& params, - const std::string& tree_name, - const std::vector& filenames) - : Emulator(params) { - TChain chain(tree_name.data()); - for (const auto& filename : filenames) - chain.Add(filename.c_str()); - - HGCModuleTreeEvent event; - chain.SetBranchAddress("event", &event.event); - chain.SetBranchAddress("chip", &event.chip); - chain.SetBranchAddress("half", &event.half); - chain.SetBranchAddress("daqdata", &event.daqdata); - chain.SetBranchAddress("bxcounter", &event.bxcounter); - chain.SetBranchAddress("eventcounter", &event.eventcounter); - chain.SetBranchAddress("orbitcounter", &event.orbitcounter); - chain.SetBranchAddress("trigtime", &event.trigtime); - chain.SetBranchAddress("trigwidth", &event.trigwidth); - - for (long long i = 0; i < chain.GetEntries(); ++i) { - chain.GetEntry(i); - - // check if event already exists - EventId key{(uint32_t)event.eventcounter, (uint32_t)event.bxcounter, (uint32_t)event.orbitcounter}; - if (data_.count(key) == 0) - data_[key] = ERxInput{}; - - // check if chip already exists - ERxId_t erxKey{(uint8_t)event.chip, (uint8_t)event.half}; - if (data_[key].count(erxKey) == 0) - data_[key][erxKey] = ERxData{}; - - // daqdata: header, CM, 37 ch, CRC32, idle - if (const auto nwords = event.daqdata->size(); nwords != 41) - throw cms::Exception("HGCalModuleTreeReader") - << "Invalid number of words retrieved for event {" << event.eventcounter << ":" << event.bxcounter << ":" - << event.orbitcounter << "}: should be 41, got " << nwords << "."; - - // 1st word is the header: discard - // 2nd word are the common mode words - - const uint32_t cmword(event.daqdata->at(1)); - if (((cmword >> 20) & 0xfff) != 0) - throw cms::Exception("HGCalModuleTreeReader") - << "Consistency check failed for common mode word: " << ((cmword >> 20) & 0xfff) << " != 0."; - - data_[key][erxKey].cm1 = cmword & 0x3ff; - data_[key][erxKey].cm0 = (cmword >> 10) & 0x3ff; - - // next 37 words are channel data - for (size_t i = 2; i < 2 + params_.num_channels_per_erx; i++) { - HGCROCChannelDataFrame frame(0, event.daqdata->at(i)); - const auto tctp = static_cast(frame.tctp()); - data_[key][erxKey].tctp.push_back(tctp); - data_[key][erxKey].adcm.push_back(frame.adcm1()); - data_[key][erxKey].adc.push_back(tctp == ToTStatus::ZeroSuppressed ? frame.adc() : 0); - data_[key][erxKey].tot.push_back(tctp == ToTStatus::ZeroSuppressed ? frame.rawtot() : 0); - data_[key][erxKey].toa.push_back(frame.toa()); - } - - // copy CRC32 - data_[key][erxKey].crc32 = event.daqdata->at(39); - - // we could assert the idle word from #40 if needed - - // copy metadata - data_[key][erxKey].meta.push_back(event.trigtime); - data_[key][erxKey].meta.push_back(event.trigwidth); - } - - edm::LogInfo("HGCalModuleTreeReader") << "read " << data_.size() << " events."; - - it_data_ = data_.begin(); -} - -// -ECONDInput HGCalModuleTreeReader::next() { - if (it_data_ == data_.end()) - throw cms::Exception("HGCalModuleTreeReader") << "Insufficient number of events were retrieved from input tree to " - "proceed with the generation of emulated events."; - - ++it_data_; - return ECONDInput{it_data_->first, it_data_->second}; -} diff --git a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc index d3e108a87b5df..2d4bc1f6dd0e3 100644 --- a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc +++ b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc @@ -1,708 +1,351 @@ -/**************************************************************************** - * - * This is a part of HGCAL offline software. - * Authors: - * Yulun Miao, Northwestern University - * Huilin Qu, CERN - * Laurent Forthomme, CERN - * - ****************************************************************************/ - #include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h" - +#include "DataFormats/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/Exception.h" -template -HGCalUnpacker::HGCalUnpacker(HGCalUnpackerConfig config) - : config_(config), - channelData_(config_.channelMax), - commonModeIndex_(config_.channelMax), - commonModeData_(config_.commonModeMax) {} - -template -void HGCalUnpacker::parseSLink( - const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping) { - uint16_t sLink = 0; - - channelDataSize_ = 0; - commonModeDataSize_ = 0; - badECOND_.clear(); - - for (uint32_t iword = 0; iword < inputArray.size();) { // loop through the S-Link - //----- parse the S-Link header - if (((inputArray[iword] >> kSLinkBOEShift) & kSLinkBOEMask) != config_.sLinkBOE) // sanity check - throw cms::Exception("CorruptData") - << "Expected a S-Link header at word " << std::dec << iword << "/0x" << std::hex << iword << " (BOE: 0x" - << config_.sLinkBOE << "), got 0x" << inputArray[iword] << "."; - - iword += 4; // length of the S-Link header (128 bits) - - LogDebug("HGCalUnpack") << "SLink=" << sLink; - - //----- parse the S-Link body - for (uint8_t captureBlock = 0; captureBlock < config_.sLinkCaptureBlockMax; - captureBlock++) { // loop through all capture blocks - //----- parse the capture block header - if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) != - config_.captureBlockReserved) // sanity check - throw cms::Exception("CorruptData") - << "Expected a capture block header at word " << std::dec << iword << "/0x" << std::hex << iword - << " (reserved word: 0x" << config_.captureBlockReserved << "), got 0x" << inputArray[iword] << "."; - - const uint64_t captureBlockHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]); - iword += 2; // length of capture block header (64 bits) - - LogDebug("HGCalUnpack") << "Capture block=" << (int)captureBlock << ", capture block header=0x" << std::hex - << captureBlockHeader; - - //----- parse the capture block body - for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) { // loop through all ECON-Ds - if (((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) >= 0b100) - continue; // only pick active ECON-Ds - - //----- parse the ECON-D header - // (the second word of ECON-D header contains no information for unpacking, use only the first one) - if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker) // sanity check - throw cms::Exception("CorruptData") - << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword - << " (marker: 0x" << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << "."; - - const auto& econdHeader = inputArray[iword]; - iword += 2; // length of ECON-D header (2 * 32 bits) - - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex - << econdHeader; - - //----- extract the payload length - const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask; - if (payloadLength > config_.payloadLengthMax) // if payload length too big - throw cms::Exception("CorruptData") << "Unpacked payload length=" << payloadLength - << " exceeds the maximal length=" << config_.payloadLengthMax; - - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length=" << payloadLength; - //Quality check - if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) || - (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) || - (((econdHeader >> kMatchShift) & kMatchMask) == 0) || - (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) { // bad ECOND - LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask) - << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask) - << ", M=" << (econdHeader >> kMatchShift & kMatchMask) - << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask); - badECOND_.emplace_back(iword - 2); - iword += payloadLength; // skip the current ECON-D (using the payload length parsed above) - - if (iword % 2 != 0) { //TODO: check this - LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ")."; - iword += 1; - } - continue; // go to the next ECON-D - } - const uint32_t econdBodyStart = iword; // for the ECON-D length check - //----- parse the ECON-D body - if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) { - // standard ECON-D - LogDebug("HGCalUnpack") << "Standard ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { - //loop through eRx - //pick active eRx - if ((enabledERX >> erx & 1) == 0) - continue; - - //----- parse the eRX subpacket header - //common mode - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx - << ", first word of the eRx header=0x" << std::hex << inputArray[iword] << "\n" - << " extracted common mode 0=0x" << std::hex - << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec - << ", saved at " << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec - << ", saved at " << (commonModeDataSize_ + 1); - commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; - } - // empty check - if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) { // empty - LogDebug("HGCalUnpack") << "eRx empty"; - iword += 1; // length of an empty eRx header (32 bits) - continue; // go to the next eRx - } - // regular mode - const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]); - iword += 2; // length of a standard eRx header (2 * 32 bits) - LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader; - - //----- parse the eRx subpacket body - uint32_t bitCounter = 0; - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through all channels in eRx - if (((erxHeader >> channel) & 1) == 0) - continue; // only pick active channels - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - const uint32_t tempIndex = bitCounter / 32 + iword; - const uint8_t tempBit = bitCounter % 32; - const uint32_t temp = - (tempBit == 0) ? inputArray[tempIndex] - : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit)); - const uint8_t code = temp >> 28; - // use if and else here - channelData_[channelDataSize_] = HGCROCChannelDataFrame( - logicalMapping(id), - ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]); - bitCounter += erxBodyBits_[code]; - if (code == 0b0010) - channelData_[channelDataSize_].fillFlag1(1); - LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel << "\n" - << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_) - << "\n" - << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x" - << std::hex << (int)code << std::dec << "\n" - << " extracted channel data=0x" << std::hex - << channelData_[channelDataSize_].raw(); - channelDataSize_++; - } - // pad to the whole word - iword += bitCounter / 32; - if (bitCounter % 32 != 0) - iword += 1; - - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; - // eRx subpacket has no trailer - } - } else { - // passthrough ECON-D - LogDebug("HGCalUnpack") << "Passthrough ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { // loop through all eRxs - if ((enabledERX >> erx & 1) == 0) - continue; // only pick active eRxs - - //----- eRX subpacket header - // common mode - uint32_t temp = inputArray[iword]; - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx - << ", first word of the eRx header=0x" << std::hex << temp << std::dec << "\n" - << " extracted common mode 0=0x" << std::hex - << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at " - << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at " - << (commonModeDataSize_ + 1); - commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; - } - iword += 2; // length of the standard eRx header (2 * 32 bits) - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through all channels in eRx - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - channelData_[channelDataSize_] = - HGCROCChannelDataFrame(logicalMapping(id), inputArray[iword]); - LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw() - << ", assigned common mode index=" << commonModeIndex_.at(channelDataSize_) - << "\n" - << "extracted channel data=0x" << std::hex - << channelData_.at(channelDataSize_).raw(); - channelDataSize_++; - iword++; - } - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; - } - } - //----- parse the ECON-D trailer - // (no information needed from ECON-D trailer in unpacker, skip it) - iword += 1; // length of the ECON-D trailer (32 bits CRC) - - if (iword - econdBodyStart != payloadLength) - throw cms::Exception("CorruptData") - << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n" - << " unpacked payload length=" << iword - econdBodyStart << "\n" - << " expected payload length=" << payloadLength; - // pad to 2 words - if (iword % 2 != 0) { //TODO: check this - LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ")."; - iword += 1; - } - } - //----- capture block has no trailer - // pad to 4 words - if (iword % 4 != 0) { //TODO: check this - LogDebug("HGCalUnpacker") << "Padding capture block to 4 32-bit words (remainder: " << (iword % 4) << ")."; - iword += 4 - (iword % 4); - } +#include + +using namespace hgcal; + +uint8_t HGCalUnpacker::parseFEDData(unsigned fedId, + const FEDRawData& fed_data, + const HGCalMappingModuleIndexer& moduleIndexer, + const HGCalConfiguration& config, + hgcaldigi::HGCalDigiHost& digis, + hgcaldigi::HGCalECONDPacketInfoHost& econdPacketInfo, + bool headerOnlyMode) { + // ReadoutSequence object for this FED + const auto& fedReadoutSequence = moduleIndexer.fedReadoutSequences_[fedId]; + // Configuration object for this FED + const auto& fedConfig = config.feds[fedId]; + + // helper functions + auto to_32b_words = [](const uint64_t* ptr_64b) { + auto* ptr_32b = reinterpret_cast(ptr_64b); + return std::array{{ptr_32b[1], ptr_32b[0]}}; + }; + + auto to_econd_payload = [](const uint64_t* ptr_64b, uint64_t payload_length) -> std::vector { + std::vector payload(payload_length, 0); + auto* ptr_32b = reinterpret_cast(ptr_64b); + for (unsigned i = 0; i < payload_length; ++i) { + payload[i] = ptr_32b[(i % 2 == 0) ? i + 1 : i - 1]; } - //----- parse the S-Link trailer - // (no information is needed in unpacker) - - iword += 4; // length of the S-Link trailer (128 bits) - sLink++; + return payload; + }; + + // Endianness assumption + // From 32-bit word(ECOND) to 64-bit word(capture block): little endianness + // Others: big endianness + const auto* const header = reinterpret_cast(fed_data.data()); + const auto* const trailer = reinterpret_cast(fed_data.data() + fed_data.size()); + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << " nwords (64b) = " << std::distance(header, trailer); + + const auto* ptr = header; + for (unsigned iword = 0; ptr < trailer; ++iword) { + LogDebug("[HGCalUnpacker]") << std::setw(8) << iword << ": 0x" << std::hex << std::setfill('0') << std::setw(16) + << *ptr << " (" << std::setfill('0') << std::setw(8) + << *(reinterpret_cast(ptr) + 1) << " " << std::setfill('0') + << std::setw(8) << *reinterpret_cast(ptr) << ")" << std::dec; + ++ptr; } - channelData_.resize(channelDataSize_); - commonModeIndex_.resize(channelDataSize_); - commonModeData_.resize(commonModeDataSize_); - return; -} - -template -void HGCalUnpacker::parseCaptureBlock( - const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping) { - uint16_t sLink = 0; - uint8_t captureBlock = 0; - - channelDataSize_ = 0; - commonModeDataSize_ = 0; - badECOND_.clear(); - - for (uint32_t iword = 0; iword < inputArray.size();) { // loop through all capture blocks - - //----- parse the capture block header - if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) != config_.captureBlockReserved) - throw cms::Exception("CorruptData") - << "Expected a capture block header at word " << std::dec << iword << "/0x" << std::hex << iword - << " (reserved word: 0x" << config_.captureBlockReserved << "), got 0x" << inputArray[iword] << "."; - - const uint64_t captureBlockHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]); - LogDebug("HGCalUnpack") << "Capture block=" << (int)captureBlock << ", capture block header=0x" << std::hex - << captureBlockHeader; - iword += 2; // length of capture block header (64 bits) - - //----- parse the capture block body - for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) { // loop through all ECON-Ds - if ((captureBlockHeader >> (3 * econd) & kCaptureBlockECONDStatusMask) >= 0b100) - continue; // only pick the active ECON-Ds - - //----- parse the ECON-D header - // (the second word of ECON-D header contains no information useful for unpacking, use only the first one) - if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker) // sanity check - throw cms::Exception("CorruptData") - << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword << " (marker: 0x" - << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << "."; - - const uint32_t econdHeader = inputArray[iword]; - iword += 2; // length of ECON-D header (2 * 32 bits) - - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex - << econdHeader; - - //----- extract the payload length - const uint32_t payloadLength = ((econdHeader >> kPayloadLengthShift)) & kPayloadLengthMask; - if (payloadLength > config_.payloadLengthMax) // payload length is too large - throw cms::Exception("CorruptData") << "Unpacked payload length=" << payloadLength - << " exceeds the maximal length=" << config_.payloadLengthMax; - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length = " << payloadLength; - if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) || - (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) || - (((econdHeader >> kMatchShift) & kMatchMask) == 0) || - (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) { // quality check failed: bad ECON-D - LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask) - << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask) - << ", M=" << (econdHeader >> kMatchShift & kMatchMask) - << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask); - badECOND_.emplace_back(iword - 2); - iword += payloadLength; // skip the current ECON-D (using the payload length parsed above) + LogDebug("[HGCalUnpacker]") << "@@@\n"; + ptr = header; + // check SLink header (128b) + // sanity check + auto slink_header = *(ptr + 1); + if (((slink_header >> (BACKEND_FRAME::SLINK_BOE_POS + 32)) & BACKEND_FRAME::SLINK_BOE_MASK) != + fedConfig.slinkHeaderMarker) { + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdPacketInfo.view()[ECONDdenseIdx].exception() = 1; + econdPacketInfo.view()[ECONDdenseIdx].location() = 0; + edm::LogWarning("[HGCalUnpacker]") << "Expected a S-Link header (BOE: 0x" << std::hex << fedConfig.slinkHeaderMarker + << "), got 0x" << std::hex + << ((slink_header >> (BACKEND_FRAME::SLINK_BOE_POS + 32)) & + BACKEND_FRAME::SLINK_BOE_MASK) + << " from " << slink_header << "."; + return UNPACKER_STAT::WrongSLinkHeader; + } - if (iword % 2 != 0) { //TODO: check this - LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ")."; - iword += 1; + ptr += 2; + // counter for the global index of ECON-D in the FED + // initialize with -1 (overflow) to start with 0 in the loop + uint32_t globalECONDIdx = static_cast(-1); + + // parse SLink body (capture blocks) + for (uint32_t captureblockIdx = 0; captureblockIdx < HGCalMappingModuleIndexer::maxCBperFED_ && ptr < trailer - 2; + captureblockIdx++) { + // check capture block header (64b) + LogDebug("[HGCalUnpacker]") << "@" << std::setw(8) << std::distance(header, ptr) << ": 0x" << std::hex + << std::setfill('0') << std::setw(16) << *ptr << std::dec; + auto cb_header = *ptr; + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx + << ", cb_header = " << std::hex << std::setfill('0') << std::setw(16) << cb_header + << std::dec; + // sanity check + if (((cb_header >> (BACKEND_FRAME::CAPTUREBLOCK_RESERVED_POS + 32)) & BACKEND_FRAME::CAPTUREBLOCK_RESERVED_MASK) != + fedConfig.cbHeaderMarker) { + //if word is a 0x0 it probably means that it's a 64b padding word: check that we are ending + //the s-link may have less capture blocks than the maxCBperFED_ so for now this is considered normal + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdPacketInfo.view()[ECONDdenseIdx].location() = (uint32_t)(ptr - header); + if (cb_header == 0x0) { + auto nToEnd = (fed_data.size() / 8 - 2) - std::distance(header, ptr); + if (nToEnd == 1) { + ptr++; + LogDebug("[HGCalUnpacker]") + << "fedId = " << fedId + << ", 64b padding word caught before parsing all max capture blocks, captureblockIdx = " + << captureblockIdx; + econdPacketInfo.view()[ECONDdenseIdx].exception() = 7; + return UNPACKER_STAT::Normal; } - continue; // go to the next ECON-D + } + econdPacketInfo.view()[ECONDdenseIdx].exception() = 2; + edm::LogWarning("[HGCalUnpacker]") << "Expected a capture block header at word " << std::dec + << (uint32_t)(ptr - header) << "/0x" << std::hex << (uint32_t)(ptr - header) + << " (reserved word: 0x" << fedConfig.cbHeaderMarker << "), got 0x" + << ((cb_header >> (BACKEND_FRAME::CAPTUREBLOCK_RESERVED_POS + 32)) & + BACKEND_FRAME::CAPTUREBLOCK_RESERVED_MASK) + << " from 0x" << cb_header << "."; + return UNPACKER_STAT::WrongCaptureBlockHeader; + } + ++ptr; + // parse Capture Block body (ECON-Ds) + for (uint32_t econdIdx = 0; econdIdx < HGCalMappingModuleIndexer::maxECONDperCB_; econdIdx++) { + auto econd_pkt_status = (cb_header >> (3 * econdIdx)) & 0b111; + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx + << ", econdIdx = " << econdIdx << ", econd_pkt_status = " << econd_pkt_status; + if (econd_pkt_status != backend::ECONDPacketStatus::InactiveECOND) { + // always increment the global ECON-D index (unless inactive/unconnected) + globalECONDIdx++; } - //----- parse the ECON-D body - const uint32_t econdBodyStart = iword; // for the ECON-D length check - if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) { - // standard ECON-D - LogDebug("HGCalUnpack") << "Standard ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { // loop through all eRxs - if ((enabledERX >> erx & 1) == 0) - continue; // only pick active eRx + bool pkt_exists = + (econd_pkt_status == backend::ECONDPacketStatus::Normal) || + (econd_pkt_status == backend::ECONDPacketStatus::PayloadCRCError) || + (econd_pkt_status == backend::ECONDPacketStatus::EventIDMismatch) || + (fedConfig.mismatchPassthroughMode && econd_pkt_status == backend::ECONDPacketStatus::BCIDOrbitIDMismatch); + if (!pkt_exists) { + continue; + } - //----- parse the eRX subpacket header - // common mode - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx - << ", first word of the eRx header=0x" << std::hex << inputArray[iword] << std::dec - << "\n" - << " extracted common mode 0=0x" << std::hex - << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec - << ", saved at " << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec - << ", saved at " << (commonModeDataSize_ + 1); + // ECON-D header (two 32b words) + LogDebug("[HGCalUnpacker]") << "@" << std::setw(8) << std::distance(header, ptr) << ": 0x" << std::hex + << std::setfill('0') << std::setw(16) << *ptr << std::dec; + auto econd_headers = to_32b_words(ptr); + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, globalECONDIdx); + econdPacketInfo.view()[ECONDdenseIdx].location() = (uint32_t)(ptr - header); + // sanity check + if (((econd_headers[0] >> ECOND_FRAME::HEADER_POS) & ECOND_FRAME::HEADER_MASK) != + fedConfig.econds[globalECONDIdx].headerMarker) { + econdPacketInfo.view()[ECONDdenseIdx].exception() = 3; + edm::LogWarning("[HGCalUnpacker]") + << "Expected a ECON-D header at word " << std::dec << (uint32_t)(ptr - header) << "/0x" << std::hex + << (uint32_t)(ptr - header) << " (marker: 0x" << fedConfig.econds[globalECONDIdx].headerMarker + << "), got 0x" << econd_headers[0] << "."; + return UNPACKER_STAT::WrongECONDHeader; + } + ++ptr; + + econdPacketInfo.view()[ECONDdenseIdx].cbFlag() = (uint8_t)(econd_pkt_status); + // ECON-D payload length (num of 32b words) + // NOTE: in the capture blocks, ECON-D packets do not have the trailing IDLE word + const auto econd_payload_length = ((econd_headers[0] >> ECOND_FRAME::PAYLOAD_POS) & ECOND_FRAME::PAYLOAD_MASK); + if (econd_payload_length > 469) { + econdPacketInfo.view()[ECONDdenseIdx].exception() = 4; + edm::LogWarning("[HGCalUnpacker]") + << "Unpacked payload length=" << econd_payload_length << " exceeds the maximal length=469"; + return UNPACKER_STAT::ECONDPayloadLengthOverflow; + } + const auto econdFlag = ((econd_headers[0] >> ECOND_FRAME::BITT_POS) & 0b1111111) + + (((econd_headers[1] >> ECOND_FRAME::BITS_POS) & 0b1) << hgcaldigi::ECONDFlag::BITS_POS); + econdPacketInfo.view()[ECONDdenseIdx].payloadLength() = (uint16_t)econd_payload_length; + econdPacketInfo.view()[ECONDdenseIdx].econdFlag() = (uint8_t)econdFlag; + econdPacketInfo.view()[ECONDdenseIdx].exception() = 0; + + // convert ECON-D packets into 32b words -- need to swap the order of the two 32b words in the 64b word + auto econd_payload = to_econd_payload(ptr, econd_payload_length); + + // forward ptr to the next ECON-D; use integer division with (... + 1) / 2 to round up + ptr += (econd_payload_length + 1) / 2; + + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx + << ", econdIdx = " << econdIdx << ", econd_headers = " << std::hex + << std::setfill('0') << std::setw(8) << econd_headers[0] << " " << econd_headers[1] + << std::dec << ", econd_payload_length = " << econd_payload_length; + + //quality check for ECON-D (no need to check again econd_pkt_status here again) + if ((((econd_headers[0] >> ECOND_FRAME::HT_POS) & ECOND_FRAME::HT_MASK) >= 0b10) || + (((econd_headers[0] >> ECOND_FRAME::EBO_POS) & ECOND_FRAME::EBO_MASK) >= 0b10) || + (((econd_headers[0] >> ECOND_FRAME::BITM_POS) & 0b1) == 0) || + (((econd_headers[0] >> ECOND_FRAME::BITM_POS) & 0b1) == 0) || econd_payload_length == 0 || headerOnlyMode) { + continue; + } - commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; + // parse ECON-D body(eRx subpackets) + const auto enabledErx = fedReadoutSequence.enabledErx_[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; + if (!pass_through_mode) { + // Standard ECON-D + LogDebug("[HGCalUnpacker]") << "Standard ECON-D, erxMax=" << erxMax << "enabledErx= " << enabledErx; + for (uint32_t erxIdx = 0; erxIdx < erxMax; erxIdx++) { + // check if the eRx is enabled + if ((enabledErx >> erxIdx & 1) == 0) { + continue; } - - // empty check - if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) { + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx + << ", econdIdx = " << econdIdx << ", erxIdx=" << erxIdx; + + econdPacketInfo.view()[ECONDdenseIdx].cm()(erxIdx,0) = (econd_payload[iword] >> ECOND_FRAME::COMMONMODE0_POS) & ECOND_FRAME::COMMONMODE0_MASK; + econdPacketInfo.view()[ECONDdenseIdx].cm()(erxIdx,1) = (econd_payload[iword] >> ECOND_FRAME::COMMONMODE1_POS) & ECOND_FRAME::COMMONMODE1_MASK; + // check if the eRx sub-packet is empty (the "F" flag in the eRx sub-packet header) + if (((econd_payload[iword] >> ECOND_FRAME::ERXFORMAT_POS) & ECOND_FRAME::ERXFORMAT_MASK) == 1) { + LogDebug("[HGCalUnpacker]") << "eRx " << erxIdx << " is empty"; iword += 1; // length of an empty eRx header (32 bits) - LogDebug("HGCalUnpack") << "eRx #" << (int)erx << " is empty."; - continue; // go to next eRx + continue; // go to the next eRx } - // regular mode - const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | (uint64_t)inputArray[iword + 1]; - LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader; - iword += 2; // length of a standard eRx header (2 * 32 bits) + // erx header + uint16_t cmSum = ((econd_payload[iword] >> ECOND_FRAME::COMMONMODE0_POS) & ECOND_FRAME::COMMONMODE0_MASK) + + ((econd_payload[iword] >> ECOND_FRAME::COMMONMODE1_POS) & ECOND_FRAME::COMMONMODE1_MASK); + uint64_t erxHeader = ((uint64_t)econd_payload[iword] << 32) | ((uint64_t)econd_payload[iword + 1]); + LogDebug("[HGCalUnpacker]") << "erx_headers = 0x" << std::hex << std::setfill('0') << std::setw(16) + << erxHeader << ", cmSum = " << std::dec << cmSum; + iword += 2; + + // parse erx body (channel data) + uint32_t iBit = 0; + for (uint32_t channelIdx = 0; channelIdx < HGCalMappingCellIndexer::maxChPerErx_; channelIdx++) { + uint32_t denseIdx = moduleIndexer.getIndexForModuleData(fedId, globalECONDIdx, erxIdx, channelIdx); + + // check if the channel has data + if (((erxHeader >> channelIdx) & 1) == 0) { + continue; + } - uint32_t bitCounter = 0; - //----- parse the eRx subpacket body - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through channels in eRx - if (((erxHeader >> channel) & 1) == 0) - continue; // only pick active channels - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - const uint32_t tempIndex = bitCounter / 32 + iword; - const uint8_t tempBit = bitCounter % 32; - const uint32_t temp = - (tempBit == 0) ? inputArray[tempIndex] - : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit)); - const uint8_t code = temp >> 28; - // use if and else here - channelData_[channelDataSize_] = HGCROCChannelDataFrame( - logicalMapping(id), - ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]); - bitCounter += erxBodyBits_[code]; - if (code == 0b0010) - channelData_[channelDataSize_].fillFlag1(1); - LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel - << ", assigned common mode index=" << commonModeIndex_[channelDataSize_] << "\n" - << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x" - << std::hex << (int)code << std::dec << "\n" - << " extracted channel data=0x" << std::hex - << channelData_[channelDataSize_].raw(); - channelDataSize_++; + const uint32_t tempIndex = iBit / 32 + iword; + const uint32_t tempBit = iBit % 32; + const uint32_t temp = (tempBit == 0) ? econd_payload[tempIndex] + : (econd_payload[tempIndex] << tempBit) | + (econd_payload[tempIndex + 1] >> (32 - tempBit)); + const uint32_t code = temp >> 28; + digis.view()[denseIdx].tctp() = tctp_[code]; + digis.view()[denseIdx].adcm1() = (temp >> adcm1Shift_[code]) & adcm1Mask_[code]; + digis.view()[denseIdx].adc() = (temp >> adcShift_[code]) & adcMask_[code]; + digis.view()[denseIdx].tot() = (temp >> totShift_[code]) & totMask_[code]; + digis.view()[denseIdx].toa() = (temp >> toaShift_[code] & toaMask_[code]); + digis.view()[denseIdx].cm() = cmSum; + digis.view()[denseIdx].flags() = 0; + iBit += erxBodyBits_[code]; } - // pad to the whole word - iword += bitCounter / 32; - if (bitCounter % 32 != 0) + iword += iBit / 32; + if (iBit % 32 != 0) { iword += 1; - - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; - // eRx subpacket has no trailer + } } - } else { // passthrough ECON-D - LogDebug("HGCalUnpack") << "Passthrough ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { // loop through all eRx - if ((enabledERX >> erx & 1) == 0) - continue; // only pick active eRx - - //----- parse the eRX subpacket header - // common mode - uint32_t temp = inputArray[iword]; - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx - << ", first word of the eRx header=0x" << std::hex << temp << std::dec << "\n" - << " extracted common mode 0=0x" << std::hex - << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at " - << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at " - << (commonModeDataSize_ + 1); - commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; + } else { + // Passthrough ECON-D + LogDebug("[HGCalUnpacker]") << "Passthrough ECON-D, erxMax=" << erxMax << "enabledErx= " << enabledErx; + for (uint32_t erxIdx = 0; erxIdx < erxMax; erxIdx++) { + // check if the eRx is enabled + if ((enabledErx >> erxIdx & 1) == 0) { + continue; } - iword += 2; // length of a standard eRx header (2 * 32 bits) - - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through all channels in eRx - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - channelData_[channelDataSize_] = - HGCROCChannelDataFrame(logicalMapping(id), inputArray[iword]); - LogDebug("HGCalUnpack") << "Word" << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw() - << ", assigned common mode index=" << commonModeIndex_[channelDataSize_] << "\n" - << "extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw(); - channelDataSize_++; - iword++; + LogDebug("[HGCalUnpacker]") << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx + << ", econdIdx = " << econdIdx << ", erxIdx=" << erxIdx; + + econdPacketInfo.view()[ECONDdenseIdx].cm()(erxIdx,0) = (econd_payload[iword] >> ECOND_FRAME::COMMONMODE0_POS) & ECOND_FRAME::COMMONMODE0_MASK; + econdPacketInfo.view()[ECONDdenseIdx].cm()(erxIdx,1) = (econd_payload[iword] >> ECOND_FRAME::COMMONMODE1_POS) & ECOND_FRAME::COMMONMODE1_MASK; + // check if the eRx sub-packet is empty (the "F" flag in the eRx sub-packet header) + if (((econd_payload[iword] >> ECOND_FRAME::ERXFORMAT_POS) & ECOND_FRAME::ERXFORMAT_MASK) == 1) { + LogDebug("[HGCalUnpacker]") << "eRx " << erxIdx << " is empty"; + iword += 1; // length of an empty eRx header (32 bits) + continue; // go to the next eRx } - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; - } - } - - //----- parse the ECON-D trailer - // (no information unpacked from ECON-D trailer, just skip it) - iword += 1; // length of an ECON-D trailer (32 bits CRC) - - if (iword - econdBodyStart != payloadLength) - throw cms::Exception("CorruptData") - << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n" - << " unpacked payload length=" << iword - econdBodyStart << "\n" - << " expected payload length=" << payloadLength; - // pad to 2 words - if (iword % 2 != 0) { - LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ")."; - iword += 1; - } - } - captureBlock++; // the capture block has no trailer to parse - } - channelData_.resize(channelDataSize_); - commonModeIndex_.resize(channelDataSize_); - commonModeData_.resize(commonModeDataSize_); - return; -} - -template -void HGCalUnpacker::parseECOND( - const std::vector& inputArray, - const std::function& enabledERXMapping, - const std::function& logicalMapping) { - uint16_t sLink = 0; - uint8_t captureBlock = 0; - uint8_t econd = 0; - channelDataSize_ = 0; - commonModeDataSize_ = 0; - badECOND_.clear(); + // erx header + uint16_t cmSum = ((econd_payload[iword] >> ECOND_FRAME::COMMONMODE0_POS) & ECOND_FRAME::COMMONMODE0_MASK) + + ((econd_payload[iword] >> ECOND_FRAME::COMMONMODE1_POS) & ECOND_FRAME::COMMONMODE1_MASK); + uint64_t erxHeader = ((uint64_t)econd_payload[iword] << 32) | ((uint64_t)econd_payload[iword + 1]); + LogDebug("[HGCalUnpacker]") << "erx_headers = 0x" << std::hex << std::setfill('0') << std::setw(16) + << erxHeader << ", cmSum = " << std::dec << cmSum; + iword += 2; - for (uint32_t iword = 0; iword < inputArray.size();) { // loop through all ECON-Ds - //----- parse the ECON-D header - // (the second word of ECON-D header contains no information for unpacking, use only the first one) - if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker) // sanity check - throw cms::Exception("CorruptData") - << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword << " (marker: 0x" - << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << "."; + // parse erx body (channel data) + for (uint32_t channelIdx = 0; channelIdx < HGCalMappingCellIndexer::maxChPerErx_; channelIdx++) { + uint32_t denseIdx = moduleIndexer.getIndexForModuleData(fedId, globalECONDIdx, erxIdx, channelIdx); - const uint32_t econdHeader = inputArray[iword]; - iword += 2; // length of ECON-D header (2 * 32 bits) - - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex - << econdHeader; - - //----- extract the payload length - const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask; - if (payloadLength > config_.payloadLengthMax) // payload length too big - throw cms::Exception("CorruptData") - << "Unpacked payload length=" << payloadLength << " exceeds the maximal length=" << config_.payloadLengthMax; - - LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length = " << payloadLength; - //Quality check - if (((econdHeader >> kHTShift & kHTMask) >= 0b10) || ((econdHeader >> kEBOShift & kEBOMask) >= 0b10) || - ((econdHeader >> kMatchShift & kMatchMask) == 0) || - ((econdHeader >> kTruncatedShift & kTruncatedMask) == 1)) { // bad ECOND - LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask) - << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask) - << ", M=" << (econdHeader >> kMatchShift & kMatchMask) - << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask); - badECOND_.emplace_back(iword - 2); - iword += payloadLength; // skip the current ECON-D (using the payload length parsed above) - - continue; // go to the next ECON-D - } - - //----- perse the ECON-D body - const uint32_t econdBodyStart = iword; // for the ECON-D length check - if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) { - // standard ECON-D - LogDebug("HGCalUnpack") << "Standard ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { // loop through all eRxs - if ((enabledERX >> erx & 1) == 0) - continue; // only pick active eRxs - - //----- parse the eRX subpacket header - // common mode - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx << ", first word of the eRx header=0x" - << std::hex << inputArray[iword] << std::dec << "\n" - << " extracted common mode 0=0x" << std::hex - << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec - << ", saved at " << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec - << ", saved at " << (commonModeDataSize_ + 1); - commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; - } - if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) { // empty eRx - LogDebug("HGCalUnpack") << "eRx empty"; - iword += 1; // length of an empty eRx header (32 bits) - - continue; // skip to the next eRx - } - - // regular mode - const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]); - iword += 2; // length of a standard eRx header (2 * 32 bits) - LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader; + // check if the channel has data + if (((erxHeader >> channelIdx) & 1) == 0) { + continue; + } - //----- parse eRx subpacket body - uint32_t bitCounter = 0; - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through all channels in eRx - if (((erxHeader >> channel) & 1) == 0) - continue; // only pick active channels - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - const uint32_t tempIndex = bitCounter / 32 + iword; - const uint8_t tempBit = bitCounter % 32; - const uint32_t temp = - (tempBit == 0) ? inputArray[tempIndex] - : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit)); - const uint8_t code = temp >> 28; - // use if and else here - channelData_[channelDataSize_] = HGCROCChannelDataFrame( - logicalMapping(id), ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]); - bitCounter += erxBodyBits_[code]; - if (code == 0b0010) - channelData_[channelDataSize_].fillFlag1(1); - LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel << "\n" - << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_) << "\n" - << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x" << std::hex - << (int)code << std::dec << "\n" - << " extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw(); - channelDataSize_++; + // check if in characterization mode + if (fedConfig.econds[globalECONDIdx].rocs[erxIdx / 2].charMode) { + //characterization mode + digis.view()[denseIdx].tctp() = (econd_payload[iword] >> 30) & 0b11; + digis.view()[denseIdx].adcm1() = 0; + digis.view()[denseIdx].adc() = (econd_payload[iword] >> 20) & 0b1111111111; + digis.view()[denseIdx].tot() = (econd_payload[iword] >> 10) & 0b1111111111; + digis.view()[denseIdx].toa() = econd_payload[iword] & 0b1111111111; + digis.view()[denseIdx].cm() = cmSum; + digis.view()[denseIdx].flags() = hgcal::DIGI_FLAG::Characterization; + } else { + //not characteristic mode + digis.view()[denseIdx].tctp() = (econd_payload[iword] >> 30) & 0b11; + + digis.view()[denseIdx].adcm1() = (econd_payload[iword] >> 20) & 0b1111111111; + if (econd_payload[iword] >> 31 & 0b1) { + digis.view()[denseIdx].adc() = 0; + digis.view()[denseIdx].tot() = (econd_payload[iword] >> 10) & 0b1111111111; + } else { + digis.view()[denseIdx].adc() = (econd_payload[iword] >> 10) & 0b1111111111; + digis.view()[denseIdx].tot() = 0; + } + digis.view()[denseIdx].toa() = econd_payload[iword] & 0b1111111111; + digis.view()[denseIdx].cm() = cmSum; + digis.view()[denseIdx].flags() = hgcal::DIGI_FLAG::Normal; + } + iword += 1; + } } - // pad to the whole word - iword += bitCounter / 32; - if (bitCounter % 32 != 0) - iword += 1; - - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; - // eRx subpacket has no trailer } - } else { - // passthrough ECON-D - LogDebug("HGCalUnpack") << "Passthrough ECON-D"; - const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd); - for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) { // loop through all eRxs - if ((enabledERX >> erx & 1) == 0) - continue; // only pick active eRx - //----- parse the eRX subpacket header - // common mode - uint32_t temp = inputArray[iword]; - LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx << ", first word of the eRx header=0x" - << std::hex << temp << std::dec << "\n" - << " extracted common mode 0=0x" << std::hex - << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at " - << commonModeDataSize_ << "\n" - << " extracted common mode 1=0x" << std::hex - << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at " - << (commonModeDataSize_ + 1); - commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask; - commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask; - if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) || - (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) { - commonModeDataSize_ += 2; - commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2]; - commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1]; - LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec - << " saved at " << commonModeDataSize_ << "\n" - << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec - << " saved at " << commonModeDataSize_ + 1; - } - iword += 2; // length of the standard eRx header (2 * 32 bits) - - for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) { // loop through all channels in eRx - const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel); - commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4; - channelData_[channelDataSize_] = - HGCROCChannelDataFrame(logicalMapping(id), inputArray[iword]); - LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":" - << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw() << "\n" - << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_) << "\n" - << "extracted channel data=0x" << std::hex << channelData_.at(channelDataSize_).raw(); - channelDataSize_++; - iword++; - } - if (commonModeDataSize_ + 1 > config_.commonModeMax) - throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1) - << " >= " << config_.commonModeMax << "."; - commonModeDataSize_ += 2; + // end of ECON-D parsing + if (iword != econd_payload_length - 1) { + econdPacketInfo.view()[ECONDdenseIdx].exception() = 5; + edm::LogWarning("[HGCalUnpacker]") + << "Mismatch between unpacked and expected ECON-D #" << (int)globalECONDIdx << " payload length\n" + << " unpacked payload length=" << iword + 1 << "\n" + << " expected payload length=" << econd_payload_length; + return UNPACKER_STAT::ECONDPayloadLengthMismatch; } } - //----- fill the ECON-D trailer - // (no information is needed from ECON-D trailer in unpacker, skip it) - iword += 1; // length of the ECON-D trailer (32 bits CRC) - - if (iword - econdBodyStart != payloadLength) - throw cms::Exception("CorruptData") - << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n" - << " unpacked payload length=" << iword - econdBodyStart << "\n" - << " expected payload length=" << payloadLength; } - channelData_.resize(channelDataSize_); - commonModeIndex_.resize(channelDataSize_); - commonModeData_.resize(commonModeDataSize_); - return; + // skip the padding word as the last capture block will be aligned to 128b if needed + if (std::distance(ptr, header) % 2) { + ++ptr; + } + // check SLink trailer (128b) + // TODO + if (ptr + 2 != trailer) { + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdPacketInfo.view()[ECONDdenseIdx].exception() = 6; + edm::LogWarning("[HGCalUnpacker]") << "Error finding the S-link trailer, expected at" << std::dec + << (uint32_t)(trailer - header) << "/0x" << std::hex + << (uint32_t)(trailer - header) << "Unpacked trailer at" << std::dec + << (uint32_t)(trailer - header + 2) << "/0x" << std::hex + << (uint32_t)(ptr - header + 2); + return UNPACKER_STAT::WrongSLinkTrailer; + } + return UNPACKER_STAT::Normal; } - -// class specialisation for the electronics ID indexing -template class HGCalUnpacker; diff --git a/EventFilter/HGCalRawToDigi/test/BuildFile.xml b/EventFilter/HGCalRawToDigi/test/BuildFile.xml index 62320375426f2..60fdabb2fdab7 100644 --- a/EventFilter/HGCalRawToDigi/test/BuildFile.xml +++ b/EventFilter/HGCalRawToDigi/test/BuildFile.xml @@ -3,12 +3,3 @@ - - - - - - - - - diff --git a/EventFilter/HGCalRawToDigi/test/HGCalUnpackerTest.cc b/EventFilter/HGCalRawToDigi/test/HGCalUnpackerTest.cc index d83ef9d377c49..1e994f0f15325 100644 --- a/EventFilter/HGCalRawToDigi/test/HGCalUnpackerTest.cc +++ b/EventFilter/HGCalRawToDigi/test/HGCalUnpackerTest.cc @@ -15,50 +15,52 @@ uint16_t enabledERXMapping(uint16_t sLink, uint8_t captureBlock, uint8_t econd) HGCalElectronicsId logicalMapping(HGCalElectronicsId elecID) { return elecID; } int main(int argc, char* argv[]) { - std::vector testInput; - if (argc > 1) { - std::ifstream file(argv[1], std::ios::in | std::ios::binary); - std::vector data((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - for (size_t i = 0; i < data.size(); i += 4) - testInput.emplace_back(((data.at(i)) & 0xff << 24) | ((data.at(i + 1) & 0xff) << 16) | - ((data.at(i + 2) & 0xff) << 8) | (data.at(i + 3) & 0xff)); - std::cout << ":::: test input ::::" << std::endl; - for (const auto& word : testInput) - std::cout << std::hex << std::setw(8) << (int)word << std::endl; - std::cout << ":::: total size: " << testInput.size() << std::endl; - } else - testInput = std::vector{ - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xfffff000, 0xaa0250bf, 0x00000000, 0xfdfffffc, - 0x00000007, 0x0fffff1f, 0xfc2fffff, 0x3fffff7f, 0xffffffff, 0xffffff00, 0xffffffff, 0x00000000, 0x00000000, - 0xaa0010ff, 0x00000000, 0xaa001f7f, 0x00000000, 0xaa0a30bf, 0x00000000, 0xfdffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x00000000, 0xffffffff, 0xffffffd3, 0xaa0050bf, 0x00000000, 0xffffffff, 0x00000000, 0xaa0090bf, 0x00000000, - 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + // TODO @hqucms - HGCalUnpackerConfig config; - config.sLinkCaptureBlockMax = 2; - HGCalUnpacker unpacker(config); - unpacker.parseSLink(testInput, enabledERXMapping, logicalMapping); + // std::vector testInput; + // if (argc > 1) { + // std::ifstream file(argv[1], std::ios::in | std::ios::binary); + // std::vector data((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + // for (size_t i = 0; i < data.size(); i += 4) + // testInput.emplace_back(((data.at(i)) & 0xff << 24) | ((data.at(i + 1) & 0xff) << 16) | + // ((data.at(i + 2) & 0xff) << 8) | (data.at(i + 3) & 0xff)); + // std::cout << ":::: test input ::::" << std::endl; + // for (const auto& word : testInput) + // std::cout << std::hex << std::setw(8) << (int)word << std::endl; + // std::cout << ":::: total size: " << testInput.size() << std::endl; + // } else + // testInput = std::vector{ + // 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xfffff000, 0xaa0250bf, 0x00000000, 0xfdfffffc, + // 0x00000007, 0x0fffff1f, 0xfc2fffff, 0x3fffff7f, 0xffffffff, 0xffffff00, 0xffffffff, 0x00000000, 0x00000000, + // 0xaa0010ff, 0x00000000, 0xaa001f7f, 0x00000000, 0xaa0a30bf, 0x00000000, 0xfdffffff, 0xffffffff, 0xffffffff, + // 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + // 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + // 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + // 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + // 0x00000000, 0xffffffff, 0xffffffd3, 0xaa0050bf, 0x00000000, 0xffffffff, 0x00000000, 0xaa0090bf, 0x00000000, + // 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; - auto channeldata = unpacker.channelData(); - auto cms = unpacker.commonModeIndex(); - for (unsigned int i = 0; i < channeldata.size(); i++) { - auto data = channeldata.at(i); - auto cm = cms.at(i); - auto id = data.id(); - auto idraw = id.raw(); - auto raw = data.raw(); - std::cout << "id=" << idraw << ", raw=" << raw << ", common mode index=" << cm << std::endl; - } - if (auto badECONDs = unpacker.badECOND(); !badECONDs.empty()) { - std::cerr << "bad ECON-Ds: " << std::dec; - std::string sep; - for (auto badECOND : badECONDs) - std::cerr << sep << badECOND, sep = ", "; - std::cerr << std::endl; - } + // HGCalUnpackerConfig config; + // config.sLinkCaptureBlockMax = 2; + // HGCalUnpacker unpacker(config); + // unpacker.parseSLink(testInput, enabledERXMapping, logicalMapping); + + // auto channeldata = unpacker.channelData(); + // auto cms = unpacker.commonModeIndex(); + // for (unsigned int i = 0; i < channeldata.size(); i++) { + // auto data = channeldata.at(i); + // auto cm = cms.at(i); + // auto id = data.id(); + // auto idraw = id.raw(); + // auto raw = data.raw(); + // std::cout << "id=" << idraw << ", raw=" << raw << ", common mode index=" << cm << std::endl; + // } + // if (auto badECONDs = unpacker.badECOND(); !badECONDs.empty()) { + // std::cerr << "bad ECON-Ds: " << std::dec; + // std::string sep; + // for (auto badECOND : badECONDs) + // std::cerr << sep << badECOND, sep = ", "; + // std::cerr << std::endl; + // } return 0; } diff --git a/EventFilter/HGCalRawToDigi/test/emulation_and_unpacking_cfg.py b/EventFilter/HGCalRawToDigi/test/emulation_and_unpacking_cfg.py deleted file mode 100644 index 5d0f898bd4db3..0000000000000 --- a/EventFilter/HGCalRawToDigi/test/emulation_and_unpacking_cfg.py +++ /dev/null @@ -1,145 +0,0 @@ -import FWCore.ParameterSet.Config as cms -import FWCore.ParameterSet.VarParsing as VarParsing - -process = cms.Process("TEST") - -options = VarParsing.VarParsing('standard') -options.register('mode', 'trivial', VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, - 'type of emulation') -options.register('fedId', 0, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'emulated FED id') -options.register('debug', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'debugging mode') -options.register('dumpFRD', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'also dump the FEDRawData content') -options.register('numCaptureBlocks', 1, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'number of capture blocks to emulate') -options.register('numECONDs', -1, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'number of ECON-Ds to emulate') -options.register('numChannelsPerERx', 37, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'number of channels enabled per ERx') -options.register('numERxsPerECOND', 12, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'number of ERxs enabled per ECON-D') -options.register('activeECONDs', [], VarParsing.VarParsing.multiplicity.list, VarParsing.VarParsing.varType.int, - 'list of ECON-Ds enabled') -options.register('ECONDsInPassthrough', [], VarParsing.VarParsing.multiplicity.list, VarParsing.VarParsing.varType.int, - 'list of ECON-Ds in passthrough mode') -options.register('ECONDsInCharacterisation', [], VarParsing.VarParsing.multiplicity.list, VarParsing.VarParsing.varType.int, - 'list of ECON-Ds in characterisation mode') -options.register('ECONDToTStatus', 3, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'default ToT status bits (aka TcTp bits) value to be emulated') -options.register('randomActiveCaptureBlocks', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'randomly activate capture blocks on emulation') -options.register('randomActiveECOND', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'randomly activate ECOn-Ds on emulation') -options.register('storeOutput', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'also store the output into an EDM file') -options.register('storeRAWOutput', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'also store the RAW output into a streamer file') -options.register('storeEmulatorInfo', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, - 'also store the emulator metadata') -options.register('inputFiles', - 'file:/eos/cms/store/group/dpg_hgcal/tb_hgcal/2023/labtest/module822/pedestal_run0.root', - VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, - 'input TB file') -options.maxEvents = 1 # number of events to emulate -options.output = 'output.root' # output EDM file -options.secondaryOutput = 'output.raw' # output streamer file -options.parseArguments() - -process.load('EventFilter.HGCalRawToDigi.hgcalEmulatedSlinkRawData_cfi') -process.load('EventFilter.HGCalRawToDigi.hgcalDigis_cfi') - -process.load("FWCore.MessageService.MessageLogger_cfi") -if options.debug: - process.MessageLogger.cerr.threshold = "DEBUG" - process.MessageLogger.debugModules = ["hgcalEmulatedSlinkRawData", "hgcalDigis"] - -process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(options.maxEvents)) -process.RandomNumberGeneratorService = cms.Service("RandomNumberGeneratorService", - hgcalEmulatedSlinkRawData = cms.PSet(initialSeed = cms.untracked.uint32(42)) -) - -process.source = cms.Source("EmptySource") - -# steer the emulator part -process.hgcalEmulatedSlinkRawData.emulatorType = options.mode -if process.hgcalEmulatedSlinkRawData.emulatorType == 'hgcmodule': - process.hgcalEmulatedSlinkRawData.inputs = cms.untracked.vstring(options.inputFiles) -process.hgcalEmulatedSlinkRawData.storeEmulatorInfo = bool(options.storeEmulatorInfo) - -# steer the number of capture blocks -if options.randomActiveCaptureBlocks: - from random import randint - process.hgcalEmulatedSlinkRawData.slinkParams.numCaptureBlocks = randint(1, 50) # randomise the number of capture blocks emulated -else: - process.hgcalEmulatedSlinkRawData.slinkParams.numCaptureBlocks = options.numCaptureBlocks -print('S-link: number of capture blocks: {}'.format( - process.hgcalEmulatedSlinkRawData.slinkParams.numCaptureBlocks.value())) - -# steer the number (and/or list) of ECON-Ds per capture block -if options.numECONDs > 0: - for i in range(options.numECONDs - len(process.hgcalEmulatedSlinkRawData.slinkParams.ECONDs)): - process.hgcalEmulatedSlinkRawData.slinkParams.ECONDs.append(process.hgcalEmulatedSlinkRawData.slinkParams.ECONDs[0].clone()) - process.hgcalEmulatedSlinkRawData.slinkParams.checkECONDsLimits = False # allows to mess with unconventional, high number - # of ECON-Ds per capture block - -econd_id = 0 -for econd in process.hgcalEmulatedSlinkRawData.slinkParams.ECONDs: - # must use 'cms.' python configuration types - if options.randomActiveECOND: # randomly turn on/off any ECON-D in capture block - from random import getrandbits - econd.active = cms.bool(bool(getrandbits(1))) - else: # use a fixed, user-steered list of ECON-Ds in capture block - econd.active = cms.bool((econd_id in options.activeECONDs)) - econd.passthroughMode = cms.bool((econd_id in options.ECONDsInPassthrough)) - econd.characterisationMode = cms.bool((econd_id in options.ECONDsInCharacterisation)) - econd.enabledERxs = cms.vuint32([i for i in range(options.numERxsPerECOND)]) - econd.numChannelsPerERx = cms.uint32(options.numChannelsPerERx) - econd.defaultToTStatus = cms.uint32(options.ECONDToTStatus) - print('ECON-D {}: active? {}, enabled eRxs: {}, number of channels/eRx: {}, passthrough? {}, characterisation? {}'.format( - econd_id, bool(econd.active), - [i for i in econd.enabledERxs], econd.numChannelsPerERx.value(), - bool(econd.passthroughMode), bool(econd.characterisationMode))) - econd_id += 1 - -# steer the unpacker -process.hgcalDigis.src = cms.InputTag('hgcalEmulatedSlinkRawData') -process.hgcalDigis.fedIds = cms.vuint32(options.fedId) -process.hgcalDigis.maxCaptureBlock = process.hgcalEmulatedSlinkRawData.slinkParams.numCaptureBlocks -process.hgcalDigis.numERxsInECOND = options.numERxsPerECOND -process.hgcalDigis.captureBlockECONDMax = max( # allows to mess with unconventional, high number of ECON-Ds per capture block - process.hgcalDigis.captureBlockECONDMax, - len([ec for ec in process.hgcalEmulatedSlinkRawData.slinkParams.ECONDs if ec.active])) - -process.p = cms.Path(process.hgcalEmulatedSlinkRawData * process.hgcalDigis) - -if options.dumpFRD: - process.dump = cms.EDAnalyzer("DumpFEDRawDataProduct", - label = cms.untracked.InputTag('hgcalEmulatedSlinkRawData'), - feds = cms.untracked.vint32(options.fedId), - dumpPayload = cms.untracked.bool(True) - ) - process.p *= process.dump - -process.outpath = cms.EndPath() - -if options.storeOutput: - process.output = cms.OutputModule("PoolOutputModule", - fileName = cms.untracked.string(options.output), - outputCommands = cms.untracked.vstring( - 'drop *', - 'keep *_hgcalEmulatedSlinkRawData_*_*', - 'keep *_hgcalDigis_*_*', - ) - ) - process.outpath += process.output - -if options.storeRAWOutput: - process.outputRAW = cms.OutputModule("FRDOutputModule", - source = cms.InputTag('hgcalEmulatedSlinkRawData'), - frdVersion = cms.untracked.uint32(6), - frdFileVersion = cms.untracked.uint32(1), - fileName = cms.untracked.string(options.secondaryOutput) - ) - process.outpath += process.outputRAW diff --git a/Geometry/HGCalMapping/interface/HGCalMappingTools.h b/Geometry/HGCalMapping/interface/HGCalMappingTools.h index d23e7a7706ba2..3de7d256d52f0 100644 --- a/Geometry/HGCalMapping/interface/HGCalMappingTools.h +++ b/Geometry/HGCalMapping/interface/HGCalMappingTools.h @@ -5,6 +5,7 @@ #include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" #include +#include namespace hgcal { @@ -41,6 +42,7 @@ namespace hgcal { 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 col) { return std::find(colNames_.begin(), colNames_.end(), col) != colNames_.end(); } private: HGCalEntityRow colNames_; @@ -81,15 +83,19 @@ namespace hgcal { key.first = i; + key.first = i; + //match cell by type of module and by cell det id DetId::Detector det(DetId::Detector::HGCalEE); uint32_t cellid = 0x3ff & HGCSiliconDetId(det, 0, 0, 0, 0, 0, siid.cellU(), siid.cellV()).rawId(); for (int j = 0; j < cells.view().metadata().size(); j++) { auto jcell = cells.view()[j]; + if (jcell.typeidx() != imod.typeidx()) continue; if (jcell.detid() != cellid) continue; + key.second = j; return key; } diff --git a/Geometry/HGCalMapping/plugins/BuildFile.xml b/Geometry/HGCalMapping/plugins/BuildFile.xml index 218f8448c948d..694c9c89548a8 100644 --- a/Geometry/HGCalMapping/plugins/BuildFile.xml +++ b/Geometry/HGCalMapping/plugins/BuildFile.xml @@ -3,6 +3,9 @@ + + + @@ -17,4 +20,4 @@ - \ No newline at end of file + diff --git a/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc b/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc index 742f1cde336ce..d925eb39c65a2 100644 --- a/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc +++ b/Geometry/HGCalMapping/plugins/HGCalMappingESProducer.cc @@ -2,19 +2,20 @@ #include "FWCore/Framework/interface/SourceFactory.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/ESProducer.h" -#include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.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/HGCalMappingModuleIndexer.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.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 @@ -102,15 +103,26 @@ void HGCalMappingESProducer::prepareModuleMapperIndexer() { auto& pmap = parsedMaps_["modules"]; auto& entities = pmap.getEntries(); for (auto row : entities) { - std::string typecode = pmap.getAttr("typecode", row); - - if (typecode.find('M') == 0 && typecode.size() > 4) - typecode = typecode.substr(0, 4); + std::string typecode = pmap.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("([MX])([LH])-([FTBLR5])([123])([WPC])-([A-Z]{2})-([0-9]{3,4})"); // MM-TTTT-LL-NNNN + const std::regex typecode_regex("(([MX])([LH])-([FTBLR5])).*"); // MM-T* + std::smatch typecode_match; // match object for string objects + bool matched = std::regex_match(typecode, typecode_match, typecode_regex); + if (matched) { + wtypecode = typecode_match[1].str(); // wafer type following MM-T pattern, e.g. "MH-F" + } else { + edm::LogWarning("HGCalMappingIndexESSource") + << "Could not match module type code to expected pattern: " << typecode; + } try { - typecodeidx = cellIndexer_.getEnumFromTypecode(typecode); - nwords = cellIndexer_.getNWordsExpectedFor(typecode); - nerx = cellIndexer_.getNErxExpectedFor(typecode); + 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); @@ -127,7 +139,7 @@ void HGCalMappingESProducer::prepareModuleMapperIndexer() { int fedid = pmap.getIntAttr("fedid", row); int captureblockidx = pmap.getIntAttr("captureblockidx", row); int econdidx = pmap.getIntAttr("econdidx", row); - modIndexer_.processNewModule(fedid, captureblockidx, econdidx, typecodeidx, nerx, nwords); + modIndexer_.processNewModule(fedid, captureblockidx, econdidx, typecodeidx, nerx, nwords, typecode); } modIndexer_.finalize(); diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc new file mode 100644 index 0000000000000..56d34b244bed7 --- /dev/null +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalDenseIndexInfoESProducer.cc @@ -0,0 +1,162 @@ +#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/HGCalMappingModuleIndexer.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 "Geometry/Records/interface/CaloGeometryRecord.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" +#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" + +#include +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcal { + + class HGCalDenseIndexInfoESProducer : public ESProducer { + public: + // + HGCalDenseIndexInfoESProducer(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")); + caloGeomToken_ = cc.consumes(); + } + + // + 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) { + //geometry + auto const& geo = iRecord.get(caloGeomToken_); + + //get cell and module indexer + auto modIndexer = iRecord.get(moduleIndexTkn_); + auto 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.getMaxDataSize(); + HGCalDenseIndexInfoHost denseIdxInfo(nIndices, cms::alpakatools::host()); + 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.globalTypesNWords_[modTypeIdx]; + int off = fedRS.chDataOffsets_[imod]; + + //get additional necessary module info + int modIdx = modIndexer.getIndexForModule(fedId, imod); + auto module_row = moduleInfo.view()[modIdx]; + bool isSiPM = module_row.isSiPM(); + uint16_t typeidx = module_row.typeidx(); + uint32_t eleid = module_row.eleid(); + uint32_t detid = module_row.detid(); + + //get the appropriate geometry + DetId::Detector det = DetId(detid).det(); + int subdet = ForwardSubdetector::ForwardEmpty; + const HGCalGeometry* hgcal_geom = + static_cast(geo.getSubdetectorGeometry(det, subdet)); + + //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.chNumber() = ich; + + row.modInfoIdx() = modIdx; + uint32_t cellIdx = cellInfoOffset + ich; + row.cellInfoIdx() = cellIdx; + + auto cell_row = cellInfo.view()[cellIdx]; + row.eleid() = eleid + cell_row.eleid(); + + //assign det id only for full and calibration cells + row.detid() = 0; + if (cell_row.t() == 1 || cell_row.t() == 0) { + if (isSiPM) { + row.detid() = ::hgcal::mappingtools::getSiPMDetId(module_row.zside(), + module_row.plane(), + module_row.i2(), + module_row.celltype(), + cell_row.i1(), + cell_row.i2()); + } else { + row.detid() = module_row.detid() + cell_row.detid(); + } + + //assign position from geometry + row.x() = 0; + row.y() = 0; + row.z() = 0; + if (hgcal_geom != nullptr) { + GlobalPoint position = hgcal_geom->getPosition(row.detid()); + row.x() = position.x(); + row.y() = position.y(); + row.z() = position.z(); + } + } + } // 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_; + edm::ESGetToken caloGeomToken_; + }; + + } // namespace hgcal + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(hgcal::HGCalDenseIndexInfoESProducer); diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc index dd72094cfb92a..bab467576710d 100644 --- a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingCellESProducer.cc @@ -10,8 +10,8 @@ #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h" -#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.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" @@ -45,11 +45,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } // - std::optional produce(const HGCalElectronicsMappingRcd& iRecord) { + std::optional produce(const HGCalElectronicsMappingRcd& iRecord) { //get cell indexer const HGCalMappingCellIndexer& cellIndexer = iRecord.get(cellIndexTkn_); const uint32_t size = cellIndexer.maxDenseIndex(); // channel-level size - HGCalMappingCellParamHostCollection cellParams(size, cms::alpakatools::host()); + HGCalMappingCellParamHost cellParams(size, cms::alpakatools::host()); for (uint32_t i = 0; i < size; i++) cellParams.view()[i].valid() = false; @@ -114,7 +114,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { cell.eleid() = HGCalElectronicsId(false, 0, 0, 0, chip * 2 + half, seq).raw(); cell.detid() = detid; } //end loop over entities - } //end loop over cell types + } //end loop over cell types return cellParams; } // end of produce() diff --git a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc index 57c425b3969fd..79324f1f9aa1b 100644 --- a/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc +++ b/Geometry/HGCalMapping/plugins/alpaka/HGCalMappingModuleESProducer.cc @@ -9,8 +9,8 @@ #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h" -#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.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" @@ -43,13 +43,13 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } // - std::optional produce(const HGCalElectronicsMappingRcd& iRecord) { + std::optional produce(const HGCalElectronicsMappingRcd& iRecord) { //get cell and module indexer auto modIndexer = iRecord.get(moduleIndexTkn_); // load dense indexing const uint32_t size = modIndexer.maxModulesIdx_; - HGCalMappingModuleParamHostCollection moduleParams(size, cms::alpakatools::host()); + HGCalMappingModuleParamHost moduleParams(size, cms::alpakatools::host()); for (size_t i = 0; i < size; i++) moduleParams.view()[i].valid() = false; @@ -63,6 +63,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { int idx = modIndexer.getIndexForModule(fedid, captureblockidx, econdidx); int typeidx = modIndexer.getTypeForModule(fedid, captureblockidx, econdidx); std::string typecode = pmap.getAttr("typecode", row); + auto celltypes = modIndexer.convertTypeCode(typecode); bool isSiPM = celltypes.first; int celltype = celltypes.second; @@ -70,8 +71,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { 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); 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; @@ -86,11 +89,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { module.plane() = plane; module.i1() = i1; module.i2() = i2; + module.irot() = irot; module.typeidx() = typeidx; module.fedid() = fedid; module.slinkidx() = pmap.getIntAttr("slinkidx", row); module.captureblock() = pmap.getIntAttr("captureblock", row); - ; module.econdidx() = econdidx; module.captureblockidx() = captureblockidx; module.eleid() = eleid; diff --git a/Geometry/HGCalMapping/python/hgcalmapping_cff.py b/Geometry/HGCalMapping/python/hgcalmapping_cff.py new file mode 100644 index 0000000000000..87d2bfd64ca05 --- /dev/null +++ b/Geometry/HGCalMapping/python/hgcalmapping_cff.py @@ -0,0 +1,26 @@ +import FWCore.ParameterSet.Config as cms + +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'): + + process.load('Geometry.HGCalMapping.hgCalMappingESProducer_cfi') + process.hgCalMappingESProducer.modules = cms.FileInPath(modules) + process.hgCalMappingESProducer.si = cms.FileInPath(sicells) + process.hgCalMappingESProducer.sipm = cms.FileInPath(sipmcells) + + if not hasattr(process, 'ProcessAcceleratorCUDA'): + print('Looks like Configuration.StandardSequences.Accelerators_cff was not yet loaded...loading') + process.load('Configuration.StandardSequences.Accelerators_cff') + + process.hgCalMappingCellESProducer = cms.ESProducer('hgcal::HGCalMappingCellESProducer@alpaka', + filelist=cms.vstring(sicells, sipmcells), + cellindexer=cms.ESInputTag('')) + process.hgCalMappingModuleESProducer = cms.ESProducer('hgcal::HGCalMappingModuleESProducer@alpaka', + filename=cms.FileInPath(modules), + moduleindexer=cms.ESInputTag('')) + process.hgCalDenseIndexInfoESProducer = cms.ESProducer('hgcal::HGCalDenseIndexInfoESProducer@alpaka', + moduleindexer=cms.ESInputTag('') ) + + return process diff --git a/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc b/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc index dcc0e66b02d9d..e950b79e8cd40 100644 --- a/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc +++ b/Geometry/HGCalMapping/test/HGCalMappingESSourceTester.cc @@ -1,4 +1,5 @@ #include +#include #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -16,29 +17,18 @@ // #include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalDenseIndexInfoRcd.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" -#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHostCollection.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingParameterHost.h" #include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" -namespace { - template - double duration(T t0, T t1) { - auto elapsed_secs = t1 - t0; - typedef std::chrono::duration float_seconds; - auto secs = std::chrono::duration_cast(elapsed_secs); - return secs.count(); - } - - inline std::chrono::time_point now() { return std::chrono::steady_clock::now(); } -} // namespace - class HGCalMappingESSourceTester : public edm::one::EDAnalyzer<> { public: explicit HGCalMappingESSourceTester(const edm::ParameterSet&); static void fillDescriptions(edm::ConfigurationDescriptions&); - std::map mapGeoToElectronics(const hgcal::HGCalMappingModuleParamHostCollection& modules, - const hgcal::HGCalMappingCellParamHostCollection& cells, + std::map mapGeoToElectronics(const hgcal::HGCalMappingModuleParamHost& modules, + const hgcal::HGCalMappingCellParamHost& cells, bool geo2ele, bool sipm); @@ -47,14 +37,19 @@ class HGCalMappingESSourceTester : public edm::one::EDAnalyzer<> { edm::ESWatcher cfgWatcher_; edm::ESGetToken cellIndexTkn_; - edm::ESGetToken cellTkn_; + edm::ESGetToken cellTkn_; edm::ESGetToken moduleIndexTkn_; - edm::ESGetToken moduleTkn_; + edm::ESGetToken moduleTkn_; + edm::ESGetToken denseIndexTkn_; }; // HGCalMappingESSourceTester::HGCalMappingESSourceTester(const edm::ParameterSet& iConfig) - : cellIndexTkn_(esConsumes()), cellTkn_(esConsumes()), moduleIndexTkn_(esConsumes()), moduleTkn_(esConsumes()) {} + : cellIndexTkn_(esConsumes()), + cellTkn_(esConsumes()), + moduleIndexTkn_(esConsumes()), + moduleTkn_(esConsumes()), + denseIndexTkn_(esConsumes()) {} // void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { @@ -178,7 +173,7 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev continue; validModules++; printf( - "\t idx=%d zside=%d isSiPM=%d plane=%d i1=%d i2=%d celltype=%d typeidx=%d fedid=%d localfedid=%d " + "\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", i, imod.zside(), @@ -186,6 +181,7 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev imod.plane(), imod.i1(), imod.i2(), + imod.irot(), imod.celltype(), imod.typeidx(), imod.fedid(), @@ -242,12 +238,13 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev int zside(0), n_i(6000000); printf("[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw ElectronicsIds\n", n_i); uint32_t elecid(0); - auto start = now(); + auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < n_i; i++) { elecid = ::hgcal::mappingtools::getElectronicsId(zside, fedid, captureblockidx, econdidx, chip, half, seq); } - auto stop = now(); - printf("\tTime: %f seconds\n", duration(start, stop)); + auto stop = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); HGCalElectronicsId eid(elecid); assert(eid.localFEDId() == fedid); @@ -262,12 +259,13 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev int plane(1), u(-9), v(-6), celltype(2), celliu(3), celliv(7); printf("[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw HGCSiliconDetIds\n", n_i); uint32_t geoid(0); - start = now(); + start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < n_i; i++) { geoid = ::hgcal::mappingtools::getSiDetId(zside, plane, u, v, celltype, celliu, celliv); } - stop = now(); - printf("\tTime: %f seconds\n", duration(start, stop)); + stop = std::chrono::high_resolution_clock::now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); HGCSiliconDetId gid(geoid); assert(gid.type() == celltype); assert(gid.layer() == plane); @@ -282,12 +280,13 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev modidx, cellidx); elecid = 0; - start = now(); + start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < n_i; i++) { elecid = modules.view()[modidx].eleid() + cells.view()[cellidx].eleid(); } - stop = now(); - printf("\tTime: %f seconds\n", duration(start, stop)); + stop = std::chrono::high_resolution_clock::now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); eid = HGCalElectronicsId(elecid); assert(eid.localFEDId() == modules.view()[modidx].fedid()); assert((uint32_t)eid.captureBlock() == modules.view()[modidx].captureblockidx()); @@ -303,17 +302,38 @@ void HGCalMappingESSourceTester::analyze(const edm::Event& iEvent, const edm::Ev modidx, cellidx); uint32_t detid(0); - start = now(); + start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < n_i; i++) { detid = modules.view()[modidx].detid() + cells.view()[cellidx].detid(); } - stop = now(); - printf("\tTime: %f seconds\n", duration(start, stop)); + stop = std::chrono::high_resolution_clock::now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); HGCSiliconDetId did(detid); assert(did.type() == modules.view()[modidx].celltype()); assert(did.layer() == modules.view()[modidx].plane()); assert(did.cellU() == cells.view()[cellidx].i1()); assert(did.cellV() == cells.view()[cellidx].i2()); + + //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 eleid modix cellidx channel x y z"); + 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.detid(), + row.eleid(), + row.modInfoIdx(), + row.cellInfoIdx(), + row.chNumber(), + row.x(), + row.y(), + row.z()); + } } // @@ -324,8 +344,8 @@ void HGCalMappingESSourceTester::fillDescriptions(edm::ConfigurationDescriptions // std::map HGCalMappingESSourceTester::mapGeoToElectronics( - const hgcal::HGCalMappingModuleParamHostCollection& modules, - const hgcal::HGCalMappingCellParamHostCollection& cells, + const hgcal::HGCalMappingModuleParamHost& modules, + const hgcal::HGCalMappingCellParamHost& cells, bool geo2ele, bool sipm) { //loop over different modules @@ -366,14 +386,6 @@ std::map HGCalMappingESSourceTester::mapGeoToElectronics( if (jcell.t() != 1) continue; - // uint32_t elecid = ::hgcal::mappingtools::getElectronicsId(imod.zside(), - // imod.fedid(), - // imod.captureblockidx(), - // imod.econdidx(), - // jcell.chip(), - // jcell.half(), - // jcell.seq()); - uint32_t elecid = imod.eleid() + jcell.eleid(); uint32_t geoid(0); @@ -382,14 +394,6 @@ std::map HGCalMappingESSourceTester::mapGeoToElectronics( geoid = ::hgcal::mappingtools::getSiPMDetId( imod.zside(), imod.plane(), imod.i2(), imod.celltype(), jcell.i1(), jcell.i2()); } else { - // geoid = ::hgcal::mappingtools::getSiDetId(imod.zside(), - // imod.plane(), - // imod.i1(), - // imod.i2(), - // imod.celltype(), - // jcell.i1(), - // jcell.i2()); - geoid = imod.detid() + jcell.detid(); } diff --git a/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc b/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc new file mode 100644 index 0000000000000..472a96cab9148 --- /dev/null +++ b/Geometry/HGCalMapping/test/alpaka/HGCalMappingESSourceTester.cc @@ -0,0 +1,433 @@ +#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 "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDPutToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/Event.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" + +#include "CondFormats/DataRecord/interface/HGCalMappingModuleIndexerRcd.h" +#include "CondFormats/DataRecord/interface/HGCalMappingModuleRcd.h" +#include "CondFormats/DataRecord/interface/HGCalMappingCellIndexerRcd.h" +#include "CondFormats/DataRecord/interface/HGCalMappingCellRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDevice.h" +#include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using namespace cms::alpakatools; + + class HGCalMappingESSourceTester : public stream::EDProducer<> { + public: + explicit HGCalMappingESSourceTester(const edm::ParameterSet&); + static void fillDescriptions(edm::ConfigurationDescriptions&); + std::map mapGeoToElectronics(const hgcal::HGCalMappingModuleParamDevice& modules, + const hgcal::HGCalMappingCellParamDevice& cells, + bool geo2ele, + bool sipm); + + private: + void produce(device::Event&, device::EventSetup const&) override; + + edm::ESWatcher cfgWatcher_; + edm::ESGetToken cellIndexTkn_; + device::ESGetToken cellTkn_; + edm::ESGetToken moduleIndexTkn_; + device::ESGetToken moduleTkn_; + }; + + // + HGCalMappingESSourceTester::HGCalMappingESSourceTester(const edm::ParameterSet& iConfig) + : cellIndexTkn_(esConsumes()), cellTkn_(esConsumes()), moduleIndexTkn_(esConsumes()), moduleTkn_(esConsumes()) {} + + // + void HGCalMappingESSourceTester::produce(device::Event& iEvent, device::EventSetup const& iSetup) { + // if the cfg didn't change there's nothing else to do + if (!cfgWatcher_.check(iSetup)) + return; + + //get cell indexers and SoA + auto cellIdx = iSetup.getData(cellIndexTkn_); + auto const& cells = iSetup.getData(cellTkn_); + printf("[HGCalMappingIndexESSourceTester][produce] Cell dense indexers and associated SoA retrieved for HGCAL\n"); + int nmodtypes = cellIdx.typeCodeIndexer_.size(); + printf("[HGCalMappingIndexESSourceTester][produce] module cell indexer has %d module types\n", nmodtypes); + + //printout and test the indexer contents for cells + printf("[HGCalMappingIndexESSourceTester][produce] Test indexer\n"); + uint32_t totOffset(0); + for (size_t idx = 0; idx < cellIdx.di_.size(); idx++) { + //check typecode exists + 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.maxErx_[idx - 1] * cellIdx.maxChPerErx_; + uint32_t delta_offset = cellIdx.offsets_[idx] - cellIdx.offsets_[idx - 1]; + assert(delta_offset == nch_prev); + } + + //assert offset is consistent with the accumulation + auto off = cellIdx.offsets_[idx]; + assert(off == totOffset); + + totOffset += cellIdx.maxErx_[idx] * cellIdx.maxChPerErx_; + + //print + printf("[HGCalMappingIndexESSourceTester][produce][%s] has index(internal)=%ld #eRx=%d #cells=%d offset=%d\n", + typecode.c_str(), + idx, + cellIdx.maxErx_[idx], + cellIdx.di_[idx].getMaxIndex(), + cellIdx.offsets_[idx]); + } + + assert(totOffset == cellIdx.maxDenseIndex()); + printf("[HGCalMappingIndexESSourceTester][produce] 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; + assert(ncells == cellIdx.maxDenseIndex()); //check for consistent size + printf("[HGCalMappingIndexESSourceTester][produce] 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 cellidx=%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.cellidx(), + icell.triglink(), + icell.trigcell(), + icell.i1(), + icell.i2(), + icell.t(), + icell.trace(), + icell.eleid(), + icell.detid()); + } + + //module mapping + auto modulesIdx = iSetup.getData(moduleIndexTkn_); + printf("[HGCalMappingIndexESSourceTester][produce] Module indexer has FEDs=%d Types in sequences=%ld max idx=%d\n", + modulesIdx.nfeds_, + modulesIdx.globalTypesCounter_.size(), + modulesIdx.maxModulesIdx_); + printf("[HGCalMappingIndexESSourceTester][produce] FED Readout sequence\n"); + std::unordered_set unique_modOffsets, unique_erxOffsets, unique_chDataOffsets; + 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.erxOffsets_.begin(), frs.erxOffsets_.end(), std::inserter(unique_erxOffsets, unique_erxOffsets.end())); + std::copy(frs.chDataOffsets_.begin(), + frs.chDataOffsets_.end(), + std::inserter(unique_chDataOffsets, unique_chDataOffsets.end())); + + size_t nmods = frs.readoutTypes_.size(); + totalmods += nmods; + printf("\t[FED %d] packs data from %ld ECON-Ds - 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.erxOffsets_[i], frs.chDataOffsets_[i]); + } + printf("\n"); + } + //check that there are unique offsets per modules in the full system + assert(unique_modOffsets.size() == totalmods); + assert(unique_erxOffsets.size() == totalmods); + assert(unique_chDataOffsets.size() == totalmods); + + //get the module mapper SoA + auto const& modules = iSetup.getData(moduleTkn_); + int nmodules = modulesIdx.maxModulesIdx_; + int validModules = 0; + assert(nmodules == modules.view().metadata().size()); //check for consistent size + printf("[HGCalMappingIndexESSourceTester][produce] 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 celltype=%d typeidx=%d fedid=%d localfedid=%d " + "captureblock=%d capturesblockidx=%d econdidx=%d eleid=0x%x detid=0x%d\n", + i, + imod.zside(), + imod.isSiPM(), + imod.plane(), + imod.i1(), + imod.i2(), + imod.celltype(), + imod.typeidx(), + imod.fedid(), + imod.slinkidx(), + imod.captureblock(), + imod.captureblockidx(), + imod.econdidx(), + imod.eleid(), + imod.detid()); + } + + printf( + "[HGCalMappingIndexESSourceTester][produce] 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 DetId to ElectronicsId mapping + auto tmap = [](auto geo2ele, auto ele2geo) { + //sizes must match + assert(geo2ele.size() == ele2geo.size()); + + //test uniqueness of keys + for (auto it : geo2ele) { + assert(ele2geo.count(it.second) == 1); + assert(ele2geo[it.second] == it.first); + } + for (auto it : ele2geo) { + assert(geo2ele.count(it.second) == 1); + assert(geo2ele[it.second] == it.first); + } + + return true; + }; + + //apply test to Si + std::map sigeo2ele = this->mapGeoToElectronics(modules, cells, true, false); + std::map 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 + std::map sipmgeo2ele = this->mapGeoToElectronics(modules, cells, true, true); + std::map 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); + + // Timing studies + uint16_t fedid(175), econdidx(2), captureblockidx(0), chip(0), half(1), seq(12), rocpin(48); + int zside(0), n_i(6000000); + printf("[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw ElectronicsIds\n", n_i); + uint32_t elecid(0); + auto start = now(); + for (int i = 0; i < n_i; i++) { + elecid = ::hgcal::mappingtools::getElectronicsId(zside, fedid, captureblockidx, econdidx, chip, half, seq); + } + auto stop = now(); + std::chrono::duration elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); + + HGCalElectronicsId eid(elecid); + assert(eid.localFEDId() == fedid); + assert((uint32_t)eid.captureBlock() == captureblockidx); + assert((uint32_t)eid.econdIdx() == econdidx); + assert((uint32_t)eid.econdeRx() == (uint32_t)(2 * chip + half)); + assert((uint32_t)eid.halfrocChannel() == seq); + float eidrocpin = (uint32_t)eid.halfrocChannel() + 36 * ((uint32_t)eid.econdeRx() % 2) - + ((uint32_t)eid.halfrocChannel() > 17) * ((uint32_t)eid.econdeRx() % 2 + 1); + assert(eidrocpin == rocpin); + + int plane(1), u(-9), v(-6), celltype(2), celliu(3), celliv(7); + printf("[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw HGCSiliconDetIds\n", n_i); + uint32_t geoid(0); + start = now(); + for (int i = 0; i < n_i; i++) { + geoid = ::hgcal::mappingtools::getSiDetId(zside, plane, u, v, celltype, celliu, celliv); + } + stop = now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); + HGCSiliconDetId gid(geoid); + assert(gid.type() == celltype); + assert(gid.layer() == plane); + assert(gid.cellU() == celliu); + assert(gid.cellV() == celliv); + + int modidx(0), cellidx(1); + printf( + "[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw ElectronicsIds from SoAs module idx: " + "%d, cell idx: %d\n", + n_i, + modidx, + cellidx); + elecid = 0; + start = now(); + for (int i = 0; i < n_i; i++) { + elecid = modules.view()[modidx].eleid() + cells.view()[cellidx].eleid(); + } + stop = now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); + eid = HGCalElectronicsId(elecid); + assert(eid.localFEDId() == modules.view()[modidx].fedid()); + assert((uint32_t)eid.captureBlock() == modules.view()[modidx].captureblockidx()); + assert((uint32_t)eid.econdIdx() == modules.view()[modidx].econdidx()); + assert((uint32_t)eid.halfrocChannel() == cells.view()[cellidx].seq()); + uint16_t econderx = cells.view()[cellidx].chip() * 2 + cells.view()[cellidx].half(); + assert((uint32_t)eid.econdeRx() == econderx); + + printf( + "[HGCalMappingIndexESSourceTester][produce] Creating %d number of raw HGCSiliconDetId from SoAs module idx: " + "%d, cell idx: %d\n", + n_i, + modidx, + cellidx); + uint32_t detid(0); + start = now(); + for (int i = 0; i < n_i; i++) { + detid = modules.view()[modidx].detid() + cells.view()[cellidx].detid(); + } + stop = now(); + elapsed = stop - start; + printf("\tTime: %f seconds\n", elapsed.count()); + HGCSiliconDetId did(detid); + assert(did.type() == modules.view()[modidx].celltype()); + assert(did.layer() == modules.view()[modidx].plane()); + assert(did.cellU() == cells.view()[cellidx].i1()); + assert(did.cellV() == cells.view()[cellidx].i2()); + } + + // + void HGCalMappingESSourceTester::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + descriptions.addWithDefaultLabel(desc); + } + + // + std::map HGCalMappingESSourceTester::mapGeoToElectronics( + const hgcal::HGCalMappingModuleParamDevice& modules, + const hgcal::HGCalMappingCellParamDevice& 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 = ::hgcal::mappingtools::getElectronicsId(imod.zside(), + // imod.fedid(), + // imod.captureblockidx(), + // imod.econdidx(), + // jcell.chip(), + // jcell.half(), + // jcell.seq()); + + uint32_t elecid = imod.eleid() + jcell.eleid(); + + uint32_t geoid(0); + + if (sipm) { + geoid = ::hgcal::mappingtools::getSiPMDetId( + imod.zside(), imod.plane(), imod.i2(), imod.celltype(), jcell.i1(), jcell.i2()); + } else { + // geoid = ::hgcal::mappingtools::getSiDetId(imod.zside(), + // imod.plane(), + // imod.i1(), + // imod.i2(), + // imod.celltype(), + // jcell.i1(), + // jcell.i2()); + + geoid = imod.detid() + 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("[HGCalMappingESSourceTester][mapGeoToElectronics] found %d duplicates with geo2ele=%d for sipm=%d\n", + ndups, + geo2ele, + sipm); + } + + return idmap; + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +// define this as a plug-in +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(HGCalMappingESSourceTester); diff --git a/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py b/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py index caff8327bc133..5cdb459aa7eab 100644 --- a/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py +++ b/Geometry/HGCalMapping/test/testMappingModuleIndexer_cfg.py @@ -17,21 +17,15 @@ input = cms.untracked.int32(1) ) -#ESSources/Producers for the logical mapping -#indexers -process.load('Geometry.HGCalMapping.hgCalMappingESProducer_cfi') -process.hgCalMappingESProducer.modules = cms.FileInPath(options.modules) -process.hgCalMappingESProducer.si = cms.FileInPath(options.sicells) -process.hgCalMappingESProducer.sipm = cms.FileInPath(options.sipmcells) +#electronics mapping +from Geometry.HGCalMapping.hgcalmapping_cff import customise_hgcalmapper +process = customise_hgcalmapper(process, + modules=options.modules, + sicells=options.sicells, + sipmcells=options.sipmcells) -#cells and modules info -process.load('Configuration.StandardSequences.Accelerators_cff') -process.hgCalMappingCellESProducer = cms.ESProducer('hgcal::HGCalMappingCellESProducer@alpaka', - filelist=cms.vstring(options.sicells,options.sipmcells), - cellindexer=cms.ESInputTag('') ) -process.hgCalMappingModuleESProducer = cms.ESProducer('hgcal::HGCalMappingModuleESProducer@alpaka', - filename=cms.FileInPath(options.modules), - moduleindexer=cms.ESInputTag('') ) +#Geometry +process.load('Configuration.Geometry.GeometryExtended2026D99Reco_cff') #tester process.tester = cms.EDAnalyzer('HGCalMappingESSourceTester') diff --git a/RecoLocalCalo/HGCalRecAlgos/BuildFile.xml b/RecoLocalCalo/HGCalRecAlgos/BuildFile.xml index 2bcf3e74e0f17..74a3224cd7496 100644 --- a/RecoLocalCalo/HGCalRecAlgos/BuildFile.xml +++ b/RecoLocalCalo/HGCalRecAlgos/BuildFile.xml @@ -1,14 +1,22 @@ - + + + + + + + - + + + - + \ No newline at end of file diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/alpaka/HGCalRecHitCalibrationAlgorithms.h b/RecoLocalCalo/HGCalRecAlgos/interface/alpaka/HGCalRecHitCalibrationAlgorithms.h new file mode 100644 index 0000000000000..cc32dea11aa7e --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/interface/alpaka/HGCalRecHitCalibrationAlgorithms.h @@ -0,0 +1,49 @@ +#ifndef RecoLocalCalo_HGCalRecAlgos_interface_alpaka_HGCalRecHitCalibrationAlgorithms_h +#define RecoLocalCalo_HGCalRecAlgos_interface_alpaka_HGCalRecHitCalibrationAlgorithms_h + +// Alpaka imports +#include +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +// HGCal digis data formats +#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h" + +// Host & devide HGCal RecHit data formats +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h" +#include "DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using namespace hgcaldigi; + using namespace hgcalrechit; + + class HGCalRecHitCalibrationAlgorithms { + public: + HGCalRecHitCalibrationAlgorithms(int n_blocks, int n_threads) : n_blocks_(n_blocks), n_threads_(n_threads) {} + + std::unique_ptr calibrate(Queue& queue, + HGCalDigiHost const& host_digis, + HGCalCalibParamDevice const& device_calib, + HGCalConfigParamDevice const& device_config) const; + + // if converting host digis to device rechits turns out too slow, we should copy host digis to device digis and then + // convert to device rechits on device + // std::unique_ptr calibrate(Queue& queue, const std::unique_ptr &digis); + + private: + void print(HGCalDigiHost const& digis, int max = -1) const; + void print_digi_device(HGCalDigiDevice const& digis, int max = -1) const; + void print_recHit_device(Queue& queue, HGCalRecHitDevice const& recHits, int max = -1) const; + + int n_blocks_; + int n_threads_; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif // RecoLocalCalo_HGCalRecAlgos_interface_alpaka_HGCalRecHitCalibrationAlgorithms_h diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/BuildFile.xml b/RecoLocalCalo/HGCalRecAlgos/plugins/BuildFile.xml new file mode 100644 index 0000000000000..843fa22caf1f8 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/BuildFile.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc new file mode 100644 index 0000000000000..572d3aae210c4 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/HGCalConfigurationESProducer.cc @@ -0,0 +1,231 @@ +#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/EventSetupRecordIntervalFinder.h" +#include "FWCore/Framework/interface/ESProducts.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/do_nothing_deleter.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" // depends on HGCalElectronicsMappingRcd +#include // for std::to_string +#include // needed to read json file with std::ifstream +#include +using json = nlohmann::json; + +/** + @short plugin parses HGCAL electronics configuration from JSON file + */ +class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder { +public: + explicit HGCalConfigurationESProducer(const edm::ParameterSet& iConfig) + : //edm::ESProducer(iConfig), + fedjson_(iConfig.getParameter("fedjson")), + modjson_(iConfig.getParameter("modjson")) { + if (iConfig.exists("bePassthroughMode")) + bePassthroughMode_ = iConfig.getParameter("bePassthroughMode"); + if (iConfig.exists("econPassthroughMode")) + econPassthroughMode_ = iConfig.getParameter("econPassthroughMode"); + if (iConfig.exists("cbHeaderMarker")) + cbHeaderMarker_ = iConfig.getParameter("cbHeaderMarker"); + if (iConfig.exists("slinkHeaderMarker")) + slinkHeaderMarker_ = iConfig.getParameter("slinkHeaderMarker"); + if (iConfig.exists("econdHeaderMarker")) + econdHeaderMarker_ = iConfig.getParameter("econdHeaderMarker"); + if (iConfig.exists("charMode")) + charMode_ = iConfig.getParameter("charMode"); + if (iConfig.exists("gain")) + gain_ = iConfig.getParameter("gain"); + auto cc = setWhatProduced(this); + //findingRecord(); + indexToken_ = cc.consumes(iConfig.getParameter("indexSource")); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("indexSource", edm::ESInputTag("")) + ->setComment("Label for module indexer to set SoA size"); + //desc.add("filename")->setComment("JSON file with FED configuration parameters"); + desc.add("fedjson", "")->setComment("JSON file with FED configuration parameters"); + desc.add("modjson", "")->setComment("JSON file with ECOND configuration parameters"); + desc.addOptional("bePassthroughMode", -1) + ->setComment("Manual override for mismatch passthrough mode in the BE"); + desc.addOptional("econPassthroughMode", -1)->setComment("Manual override passthrough mode in the ECON-D"); + desc.addOptional("cbHeaderMarker", -1) + ->setComment("Manual override for capture block header marker (BEO, e.g 0x7f)"); + desc.addOptional("slinkHeaderMarker", -1) + ->setComment("Manual override for S-link header marker (BEO, e.g 0x55)"); + desc.addOptional("econdHeaderMarker", -1) + ->setComment("Manual override for ECON-D header marker (BEO, e.g 0x154)"); + desc.addOptional("charMode", -1)->setComment("Manual override for ROC characterization mode"); + desc.addOptional("gain", -1)->setComment("Manual override for ROC gain"); + descriptions.addWithDefaultLabel(desc); + } + + static bool checkkeys(const json& data, + const std::string& firstkey, + const std::vector& keys, + const std::string& fname) { + // check if json contains key + bool iscomplete = true; + for (auto const& key : keys) { + if (not data[firstkey].contains(key)) { + edm::LogWarning("HGCalConfigurationESProducer::checkkeys") + << " JSON is missing key '" << key << "' for " << firstkey << "!" + << " Please check file " << fname; + iscomplete = false; + } + } + return iscomplete; + } + + static int32_t gethex(const std::string& value, const int32_t value_override) { + // get value, and override if value_override>=0 + return (value_override >= 0 ? value_override : std::stoi(value, nullptr, 16)); + } + + static int32_t getint(const int32_t value, const int32_t value_override) { + // get value, and override if value_override>=0 + return (value_override >= 0 ? value_override : value); + } + + //template + //static T getval(T value, int32_t value_override) { + // // get value, and override if value_override>=0 + // std::cout << "HGCalConfigurationESProducer::getval: value=" << value << ", override=" << value_override << std::endl; + // return (value_override>=0 ? (T) value_override : value); + //} + + std::unique_ptr produce(const HGCalModuleConfigurationRcd& iRecord) { + auto const& moduleMap = iRecord.get(indexToken_); + + // retrieve values from custom JSON format (see HGCalCalibrationESProducer) + edm::FileInPath fedfip(fedjson_); // e.g. HGCalCommissioning/LocalCalibration/data/config_feds.json + edm::FileInPath modfip(modjson_); // e.g. HGCalCommissioning/LocalCalibration/data/config_econds.json + //std::cout << "HGCalConfigurationESProducer::produce: fedjson=" << fedfip.fullPath() << std::endl; + //std::cout << "HGCalConfigurationESProducer::produce: modjson=" << modfip.fullPath() << std::endl; + std::ifstream fedfile(fedfip.fullPath()); + std::ifstream modfile(modfip.fullPath()); + const json fed_config_data = json::parse(fedfile); + const json mod_config_data = json::parse(modfile); + + // consistency check + uint32_t nfeds = moduleMap.getNFED(); + uint32_t ntot_mods = 0, ntot_rocs = 0; + const std::vector fedkeys = { + "mismatchPassthroughMode", "cbHeaderMarker", "slinkHeaderMarker", "econds"}; + const std::vector modkeys = {"headerMarker", "passthrough", "Gain", "CalibrationSC"}; + if (nfeds != fed_config_data.size()) + edm::LogWarning("HGCalConfigurationESProducer") + << "Total number of FEDs found in JSON file " << fedjson_ << " (" << fed_config_data.size() + << ") does not match indexer (" << nfeds << ")"; + + // loop over FEDs in indexer & fill configuration structs: FED > ECON-D > eRx + // follow indexing by HGCalMappingModuleIndexer + // HGCalConfiguration = container class holding FED structs of ECON-D structs of eRx structs + std::unique_ptr config_ = std::make_unique(); + for (std::size_t fedid = 0; fedid < moduleMap.getMaxFEDSize(); ++fedid) { + // sanity checks + //std::cout << "HGCalConfigurationESProducer::produce: fed=" << fedid << std::endl; + if (moduleMap.fedReadoutSequences_[fedid].readoutTypes_.size() == 0) // check if FED exists (non-empty) + continue; // skip non-existent FED + std::string sfedid = std::to_string(fedid); // key in JSON dictionary must be string + if (!fed_config_data.contains(sfedid)) + edm::LogWarning("HGCalConfigurationESProducer") + << " Did not find FED index " << sfedid << " in JSON file " << fedjson_ << "..."; + checkkeys(fed_config_data, sfedid, fedkeys, fedjson_); // check required keys are in the JSON, warn otherwise + + // fill FED configurations + HGCalFedConfig fed; + fed.mismatchPassthroughMode = getint(fed_config_data[sfedid]["mismatchPassthroughMode"], + bePassthroughMode_); // ignore ECON-D packet mismatches + fed.cbHeaderMarker = gethex(fed_config_data[sfedid]["cbHeaderMarker"], + cbHeaderMarker_); // begin of event marker/identifier for capture block + fed.slinkHeaderMarker = gethex(fed_config_data[sfedid]["slinkHeaderMarker"], + slinkHeaderMarker_); // begin of event marker/identifier for S-link + + // loop over ECON-D modules in JSON + for (const std::string typecode : + fed_config_data[sfedid]["econds"]) { // loop over module typecodes in JSON file (e.g. "ML-F3PT-TX-0003") + //std::cout << "HGCalConfigurationESProducer::produce: typecode=" << typecode << std::endl; + + // sanity checks for ECON-Ds + ntot_mods++; + const auto& [fedid2, imod] = moduleMap.getIndexForFedAndModule(typecode); + if (fedid != fedid2) + edm::LogWarning("HGCalConfigurationESProducer") + << " FED index from HGCalMappingModuleIndexer (" << fedid << ") does not match that of the JSON file (" + << fedid2 << ", " << fedjson_ << ") for ECON-D module with typecode " << typecode << " and id=" << imod + << "!"; + checkkeys(mod_config_data, typecode, modkeys, modjson_); // check required keys are in the JSON, warn otherwise + if (imod >= fed.econds.size()) + fed.econds.resize(imod + 1); + + // fill ECON-D configuration + HGCalECONDConfig mod; + mod.headerMarker = gethex(mod_config_data[typecode]["headerMarker"], + econdHeaderMarker_); // begin of event marker/identifier for capture block + mod.passThrough = getint(mod_config_data[typecode]["passthrough"], econPassthroughMode_); + + // sanity checks for eRx half-ROCs + uint32_t nrocs = moduleMap.getMaxERxSize(fedid, imod); + uint32_t nrocs2 = mod_config_data[typecode]["Gain"].size(); + if (nrocs != nrocs2) + edm::LogWarning("HGCalConfigurationESProducer") + << " Number of eRx ROCs for ECON-D " << typecode << " in " << fedjson_ << " (" << nrocs2 + << ") does not match that of the indexer for fedid" << fedid << " & imod=" << imod << " (" << nrocs + << ")!"; + mod.rocs.resize(nrocs); + + // fill eRX (half-ROC) configuration + for (uint32_t iroc = 0; iroc < nrocs; iroc++) { + ntot_rocs++; + HGCalROCConfig roc; + roc.gain = (uint8_t)mod_config_data[typecode]["Gain"][iroc]; + //roc.charMode = getint(mod_config_data[typecode]["characMode"],charMode_); + roc.charMode = getint(mod_config_data[typecode]["CalibrationSC"][iroc], charMode_); + mod.rocs[iroc] = roc; // add to ECON-D's vector of eRx half-ROCs + } + fed.econds[imod] = mod; // add to FED's vector of ECON-D modules + } + + config_->feds.push_back(fed); // add to config's vector of HGCalFedConfig FEDs + } + + // consistency check + if (ntot_mods != moduleMap.getMaxModuleSize()) + 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()) + edm::LogWarning("HGCalConfigurationESProducer") + << "Total number of eRx half-ROCs found in JSON file " << modjson_ << " (" << ntot_rocs + << ") does not match indexer (" << moduleMap.getMaxERxSize() << ")"; + + return config_; + } // end of produce() + +private: + void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&, + const edm::IOVSyncValue&, + edm::ValidityInterval& oValidity) override { + oValidity = edm::ValidityInterval(edm::IOVSyncValue::beginOfTime(), edm::IOVSyncValue::endOfTime()); + } + + edm::ESGetToken indexToken_; + const std::string fedjson_; // JSON file + const std::string modjson_; // JSON file + int32_t bePassthroughMode_ = -1; // for manual override + int32_t cbHeaderMarker_ = -1; // for manual override + int32_t slinkHeaderMarker_ = -1; // for manual override + int32_t econdHeaderMarker_ = -1; // for manual override + int32_t econPassthroughMode_ = -1; // for manual override + int32_t charMode_ = -1; // for manual override + int32_t gain_ = -1; // for manual override +}; + +DEFINE_FWK_EVENTSETUP_SOURCE(HGCalConfigurationESProducer); diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationAlgorithms.dev.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationAlgorithms.dev.cc new file mode 100644 index 0000000000000..d143670a310a0 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationAlgorithms.dev.cc @@ -0,0 +1,202 @@ +#include + +// CMSSW imports +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// Alpaka imports +#include "HeterogeneousCore/AlpakaInterface/interface/traits.h" +#include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" + +// HGCal imports +#include "RecoLocalCalo/HGCalRecAlgos/interface/alpaka/HGCalRecHitCalibrationAlgorithms.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using namespace cms::alpakatools; + + // + struct HGCalRecHitCalibrationKernel_flagRecHits { + template + ALPAKA_FN_ACC void operator()(TAcc const& acc, + HGCalDigiDevice::View digis, + HGCalRecHitDevice::View recHits, + HGCalCalibParamDevice::ConstView calibs) const { + for (auto idx : uniform_elements(acc, digis.metadata().size())) { + auto calib = calibs[idx]; + int calibvalid = std::to_integer(calib.valid()); + auto digi = digis[idx]; + auto digiflags = digi.flags(); + //recHits[idx].flags() = digiflags; + bool isAvailable((digiflags != hgcal::DIGI_FLAG::Invalid) && (digiflags != hgcal::DIGI_FLAG::NotAvailable) && + (calibvalid > 0)); + bool isToAavailable((digiflags != hgcal::DIGI_FLAG::ZS_ToA) && (digiflags != hgcal::DIGI_FLAG::ZS_ToA_ADCm1)); + recHits[idx].flags() = (!isAvailable) * hgcalrechit::HGCalRecHitFlags::EnergyInvalid + + (!isToAavailable) * hgcalrechit::HGCalRecHitFlags::TimeInvalid; + } + } + }; + + // + struct HGCalRecHitCalibrationKernel_adcToCharge { + template + ALPAKA_FN_ACC void operator()(TAcc const& acc, + HGCalDigiDevice::View digis, + HGCalRecHitDevice::View recHits, + HGCalCalibParamDevice::ConstView calibs) const { + auto adc_to_fC = [&](uint32_t adc, + uint32_t cm, + uint32_t adcm1, + float adc_ped, + float cm_slope, + float cm_ped, + float bxm1_slope, + float adc2fC) { + float cmf = cm_slope * (0.5 * float(cm) - cm_ped); + return adc2fC * ((adc - adc_ped) - cmf - bxm1_slope * (adcm1 - adc_ped - cmf)); + }; + + auto tot_to_fC = + [&](uint32_t tot, float tot_lin, float tot_ped, float tot2fC, float tot_p0, float tot_p1, float tot_p2) { + bool isLin(tot > tot_lin); + bool isNotLin(!isLin); + return isLin * (tot2fC * (tot - tot_ped)) + isNotLin * (tot_p0 + tot_p1 * tot + tot_p2 * tot * tot); + }; + + for (auto idx : uniform_elements(acc, digis.metadata().size())) { + auto calib = calibs[idx]; + int calibvalid = std::to_integer(calib.valid()); + auto digi = digis[idx]; + auto digiflags = digi.flags(); + bool isAvailable((digiflags != hgcal::DIGI_FLAG::Invalid) && (digiflags != hgcal::DIGI_FLAG::NotAvailable) && + (calibvalid > 0)); + bool useTOT((digi.tctp() == 3) && isAvailable); + bool useADC(!useTOT && isAvailable); + recHits[idx].energy() = useADC * adc_to_fC(digi.adc(), + digi.cm(), + digi.adcm1(), + calib.ADC_ped(), + calib.CM_slope(), + calib.CM_ped(), + calib.BXm1_slope(), + calib.ADCtofC()) + + useTOT * tot_to_fC(digi.tot(), + calib.TOT_lin(), + calib.TOTtofC(), + calib.TOT_ped(), + calib.TOT_P0(), + calib.TOT_P1(), + calib.TOT_P2()); + } + } + }; + + // + struct HGCalRecHitCalibrationKernel_toaToTime { + template + ALPAKA_FN_ACC void operator()(TAcc const& acc, + HGCalDigiDevice::View digis, + HGCalRecHitDevice::View recHits, + HGCalCalibParamDevice::ConstView calibs) const { + auto toa_to_ps = [&](uint32_t toa, float toatops) { return toa * toatops; }; + + for (auto idx : uniform_elements(acc, digis.metadata().size())) { + auto calib = calibs[idx]; + int calibvalid = std::to_integer(calib.valid()); + auto digi = digis[idx]; + auto digiflags = digi.flags(); + bool isAvailable((digiflags != hgcal::DIGI_FLAG::Invalid) && (digiflags != hgcal::DIGI_FLAG::NotAvailable) && + (calibvalid > 0)); + bool isToAavailable((digiflags != hgcal::DIGI_FLAG::ZS_ToA) && (digiflags != hgcal::DIGI_FLAG::ZS_ToA_ADCm1)); + bool isGood(isAvailable && isToAavailable); + recHits[idx].time() = isGood * toa_to_ps(digi.toa(), calib.TOAtops()); + } + } + }; + + struct HGCalRecHitCalibrationKernel_printRecHits { + template + ALPAKA_FN_ACC void operator()(TAcc const& acc, HGCalRecHitDevice::ConstView view, int size) const { + for (int i = 0; i < size; ++i) { + auto const& recHit = view[i]; + printf("%d\t%f\t%f\t%d\n", i, recHit.energy(), recHit.time(), recHit.flags()); + } + } + }; + + std::unique_ptr HGCalRecHitCalibrationAlgorithms::calibrate( + Queue& queue, + HGCalDigiHost const& host_digis, + HGCalCalibParamDevice const& device_calib, + HGCalConfigParamDevice const& device_config) const { + LogDebug("HGCalRecHitCalibrationAlgorithms") << "\n\nINFO -- Start of calibrate\n\n" << std::endl; + LogDebug("HGCalRecHitCalibrationAlgorithms") + << "N blocks: " << n_blocks_ << "\tN threads: " << n_threads_ << std::endl; + auto grid = make_workdiv(n_blocks_, n_threads_); + + LogDebug("HGCalRecHitCalibrationAlgorithms") << "\n\nINFO -- Copying the digis to the device\n\n" << std::endl; + HGCalDigiDevice device_digis(host_digis.view().metadata().size(), queue); + alpaka::memcpy(queue, device_digis.buffer(), host_digis.const_buffer()); + + LogDebug("HGCalRecHitCalibrationAlgorithms") + << "\n\nINFO -- Allocating rechits buffer and initiating values" << std::endl; + auto device_recHits = std::make_unique(device_digis.view().metadata().size(), queue); + + alpaka::exec(queue, + grid, + HGCalRecHitCalibrationKernel_flagRecHits{}, + device_digis.view(), + device_recHits->view(), + device_calib.view()); + alpaka::exec(queue, + grid, + HGCalRecHitCalibrationKernel_adcToCharge{}, + device_digis.view(), + device_recHits->view(), + device_calib.view()); + alpaka::exec(queue, + grid, + HGCalRecHitCalibrationKernel_toaToTime{}, + device_digis.view(), + device_recHits->view(), + device_calib.view()); + + LogDebug("HGCalRecHitCalibrationAlgorithms") << "Input recHits: " << std::endl; +#ifdef EDM_ML_DEBUG + int n_hits_to_print = 10; + print_recHit_device(queue, *device_recHits, n_hits_to_print); +#endif + + return device_recHits; + } + + void HGCalRecHitCalibrationAlgorithms::print(HGCalDigiHost const& digis, int max) const { + int max_ = max > 0 ? max : digis.view().metadata().size(); + for (int i = 0; i < max_; i++) { + LogDebug("HGCalRecHitCalibrationAlgorithms") + << i << digis.view()[i].tot() << "\t" << digis.view()[i].toa() << "\t" << digis.view()[i].cm() << "\t" + << digis.view()[i].flags() << std::endl; + } + } + + void HGCalRecHitCalibrationAlgorithms::print_digi_device(HGCalDigiDevice const& digis, int max) const { + int max_ = max > 0 ? max : digis.view().metadata().size(); + for (int i = 0; i < max_; i++) { + LogDebug("HGCalRecHitCalibrationAlgorithms") + << i << digis.view()[i].tot() << "\t" << digis.view()[i].toa() << "\t" << digis.view()[i].cm() << "\t" + << digis.view()[i].flags() << std::endl; + } + } + + void HGCalRecHitCalibrationAlgorithms::print_recHit_device(Queue& queue, + HGCalRecHitDevice const& recHits, + int max) const { + auto grid = make_workdiv(1, 1); + auto size = max > 0 ? max : recHits.view().metadata().size(); + alpaka::exec(queue, grid, HGCalRecHitCalibrationKernel_printRecHits{}, recHits.view(), size); + + // ensure that the print operations are complete before returning + alpaka::wait(queue); + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc new file mode 100644 index 0000000000000..8ff0349ac5e57 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitCalibrationESProducer.cc @@ -0,0 +1,169 @@ +// #include "FWCore/Framework/interface/MakerMacros.h" +// #include "FWCore/Framework/interface/SourceFactory.h" +// #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +//#include "FWCore/Utilities/interface/ESGetToken.h" +// #include "DataFormats/Math/interface/libminifloat.h" + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/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 "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" // depends on HGCalElectronicsMappingRcd +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" // for HGCalConfigParamHost +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" + +#include +#include +#include // for std::setw +#include +#include // needed to read json file with std::ifstream +#include +using json = nlohmann::json; + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcalrechit { + + class HGCalCalibrationESProducer : public ESProducer { + public: + HGCalCalibrationESProducer(const edm::ParameterSet& iConfig) + : ESProducer(iConfig), filename_(iConfig.getParameter("filename")) { + auto cc = setWhatProduced(this); + indexToken_ = cc.consumes(iConfig.getParameter("indexSource")); + configToken_ = cc.consumes(iConfig.getParameter("configSource")); + std::cout << "HGCalCalibrationESProducer::HGCalCalibrationESProducer: file=" << filename_ << std::endl; + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("filename")->setComment("Path to JSON file with calibration parameters"); + desc.add("indexSource", edm::ESInputTag("")) + ->setComment("Label for module indexer to set SoA size"); + desc.add("configSource", edm::ESInputTag("")) + ->setComment("Label for ROC configuration parameters"); + descriptions.addWithDefaultLabel(desc); + } + + template + static void fill_SoA_column( + T* column_SoA, const std::vector& values, const int offset, const int nrows, int arr_offset = 0) { + // fill SoA column with data from vector for any type + const int nrows_vals = values.size(); + if (arr_offset < 0) { + arr_offset = 0; + if (nrows_vals != arr_offset + nrows) { + edm::LogWarning("HGCalCalibrationESProducer") + << " Expected " << nrows << " rows, but got " << nrows_vals << "!"; + } + } else if (nrows_vals < arr_offset + nrows) { + edm::LogWarning("HGCalCalibrationESProducer") + << " Tried to copy " << nrows << " rows to SoA with offset " << arr_offset << ", but only have " + << nrows_vals << " values in JSON!"; + } + auto begin = values.begin() + arr_offset; + auto end = (begin + nrows > values.end()) ? values.end() : begin + nrows; + std::copy(begin, end, &column_SoA[offset]); + } + + std::optional produce(const HGCalModuleConfigurationRcd& iRecord) { + auto const& moduleMap = iRecord.get(indexToken_); + auto const& config = iRecord.get(configToken_); + + // load dense indexing + const uint32_t nchans = moduleMap.getMaxDataSize(); // channel-level size + hgcalrechit::HGCalCalibParamHost product(nchans, cms::alpakatools::host()); + //std::cout << "HGCalCalibrationESProducer::produce: moduleMap.getMaxDataSize()=" << nchans + // << ", moduleMap.getMaxERxSize()=" << nmod << std::endl; + + // load calib parameters from JSON + std::ifstream infile(filename_.fullPath().c_str()); + json calib_data = json::parse(infile); + for (const auto& it : calib_data.items()) { // loop over module typecodes in JSON file + std::string module = it.key(); // module typecode, e.g. "ML-F3PT-TX-0003" + if (module == "Metadata") + continue; // ignore metadata fields + const auto& [ifed, imod] = moduleMap.getIndexForFedAndModule(module); + const uint32_t offset = + moduleMap.getIndexForModuleData(module); // convert module typecode to dense index for this module + const uint32_t nrows = + calib_data[module]["Channel"].size(); // number of channels to compare with JSON arrays + const uint32_t nrocs = + config.feds[ifed].econds[imod].rocs.size(); // number of channels to compare with JSON arrays + //std::cout << "HGCalCalibrationESProducer::produce: calib_data[\"" << module << "\"][\"Channel\"].size() = " + // << nrows << ", offset=" << offset << ", nrocs=" << nrocs << std::endl; + + // check number of channels & ROCs make sense + uint32_t nchans = (nrows % 39 == 0 ? 39 : 37); // number of channels per eRx (37 excl. common modes) + if (nrows % 37 != 0 and nrows % 39 != 0) { + edm::LogWarning("HGCalCalibrationESProducer") + << " nchannels%nchannels_per_erX!=0 nchannels=" << nrows << ", nchannels_per_erX=37 or 39!"; + } + + // loop over ECON eRx blocks to fill columns for gain-dependent calibration parameters + for (std::size_t iroc = 0; iroc < nrocs; ++iroc) { + const uint32_t i_gain = + config.feds[ifed] + .econds[imod] + .rocs[iroc] + .gain; // index of JSON array corresponding to (index,gain) = (0,80fC), (1,160fC), (2,320fC) + const uint32_t offset_arr = iroc * nchans; // dense index offset for JSON array (input to SoA) + const uint32_t offset_soa = offset + offset_arr; // dense index offset for SoA + //std::cout << "HGCalCalibrationESProducer::produce: iroc=" << iroc << ", nchans=" << nchans + // << " => offset_soa=" << offset_soa << ", offset_arr=" << offset_arr << std::endl; + if (offset_arr + nchans > nrows) { + edm::LogWarning("HGCalCalibrationESProducer") + << " offset + nchannels_per_eRx = " << offset_arr << " + " << nchans << " = " << offset_arr + nchans + << " > " << nrows << " = nchannels "; + } + fill_SoA_column( + product.view().ADCtofC(), calib_data[module]["ADCtofC"][i_gain], offset_soa, nchans, offset_arr); + fill_SoA_column( + product.view().ADC_ped(), calib_data[module]["ADC_ped"][i_gain], offset_soa, nchans, offset_arr); + fill_SoA_column( + product.view().Noise(), calib_data[module]["Noise"][i_gain], offset_soa, nchans, offset_arr); + fill_SoA_column( + product.view().CM_slope(), calib_data[module]["CM_slope"][i_gain], offset_soa, nchans, offset_arr); + fill_SoA_column( + product.view().CM_ped(), calib_data[module]["CM_ped"][i_gain], offset_soa, nchans, offset_arr); + fill_SoA_column( + product.view().BXm1_slope(), calib_data[module]["BXm1_slope"][i_gain], offset_soa, nchans, offset_arr); + } + + // fill columns for gain-independent calibration parameters + fill_SoA_column(product.view().TOTtofC(), calib_data[module]["TOTtofC"], offset, nrows); + fill_SoA_column(product.view().TOT_ped(), calib_data[module]["TOT_ped"], offset, nrows); + fill_SoA_column(product.view().TOT_lin(), calib_data[module]["TOT_lin"], offset, nrows); + fill_SoA_column(product.view().TOT_P0(), calib_data[module]["TOT_P0"], offset, nrows); + fill_SoA_column(product.view().TOT_P1(), calib_data[module]["TOT_P1"], offset, nrows); + fill_SoA_column(product.view().TOT_P2(), calib_data[module]["TOT_P2"], offset, nrows); + fill_SoA_column(product.view().TOAtops(), calib_data[module]["TOAtops"], offset, nrows); + fill_SoA_column(product.view().MIPS_scale(), calib_data[module]["MIPS_scale"], offset, nrows); + fill_SoA_column(product.view().valid(), + calib_data[module]["Valid"], + offset, + nrows); // mybool (=std::byte) defined in HGCalCalibrationParameterSoA.h + } + + return product; + } // end of produce() + + private: + edm::ESGetToken indexToken_; + edm::ESGetToken configToken_; + const edm::FileInPath filename_; + }; + + } // namespace hgcalrechit + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(hgcalrechit::HGCalCalibrationESProducer); diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitConfigurationESProducer.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitConfigurationESProducer.cc new file mode 100644 index 0000000000000..61cd28bcd0d93 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitConfigurationESProducer.cc @@ -0,0 +1,99 @@ +#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/ESTransientHandle.h" +#include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "DataFormats/Math/interface/libminifloat.h" + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/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/HGCalObjects/interface/HGCalConfiguration.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" // depends on HGCalElectronicsMappingRcd +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" // for HGCalConfigParamHost +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" + +#include +#include // for std::cout +#include // for std::setw +//#include // needed to read json file with std::ifstream +//#include +//using json = nlohmann::json; + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace hgcalrechit { + + class HGCalConfigurationESProducer : public ESProducer { + public: + HGCalConfigurationESProducer(const edm::ParameterSet& iConfig) : ESProducer(iConfig) { + if (iConfig.exists("gain")) + gain_ = iConfig.getParameter("gain"); + auto cc = setWhatProduced(this); //HGCalConfigurationESProducer::produce + indexToken_ = cc.consumes(iConfig.getParameter("indexSource")); + configToken_ = cc.consumes(iConfig.getParameter("configSource")); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("indexSource", edm::ESInputTag("")) + ->setComment("Label for module indexer to set SoA size"); + desc.add("configSource", edm::ESInputTag("")) + ->setComment("Label for ROC configuration parameters"); + desc.addOptional("gain", 2)->setComment( + "Manual override for gain for all modules (1: 80 fC, 2: 160 fC, 4: 320 fC)"); + descriptions.addWithDefaultLabel(desc); + } + + std::optional produce(const HGCalModuleConfigurationRcd& iRecord) { + auto const& config = iRecord.get(configToken_); + auto const& moduleMap = iRecord.get(indexToken_); + + // load dense indexing + const uint32_t nERx = moduleMap.getMaxERxSize(); // half-ROC-level size + hgcalrechit::HGCalConfigParamHost product(nERx, cms::alpakatools::host()); + //std::cout << "HGCalConfigurationESProducer::produce: moduleMap.getMaxDataSize()=" << moduleMap.getMaxDataSize() + // << ", moduleMap.getMaxERxSize()=" << nERx + // << ", moduleMap.getMaxModuleSize()=" << moduleMap.getMaxModuleSize() << std::endl; + + // fill SoA with gain + if (gain_ > 0) { // fill with single value from user override + //std::cout << "HGCalConfigurationESProducer::produce: fill with default, gain=" << gain_ << std::endl; + for (uint32_t iroc = 0; iroc < nERx; iroc++) { + product.view()[iroc].gain() = gain_; + } + } else { // fill with ROC-dependent value from JSON via HGCalConfiguration + for (uint32_t ifed = 0; ifed < config.feds.size(); ++ifed) { + for (uint32_t imod = 0; imod < config.feds[ifed].econds.size(); ++imod) { + for (uint32_t iroc = 0; iroc < config.feds[ifed].econds[imod].rocs.size(); ++iroc) { + //uint32_t i = getIndexForModuleErx(ifed,imod,iroc); // dense index for ROCs + uint32_t iroc_dense = moduleMap.getIndexForModuleErx(ifed, imod, iroc); // dense index for eRx half-ROC + product.view()[iroc_dense].gain() = config.feds[ifed].econds[imod].rocs[iroc].gain; + } + } + } + } + + return product; + } // end of produce() + + private: + edm::ESGetToken indexToken_; + edm::ESGetToken configToken_; + int32_t gain_ = -1; // manual override of YAML files + }; + + } // namespace hgcalrechit + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(hgcalrechit::HGCalConfigurationESProducer); diff --git a/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitProducers.cc b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitProducers.cc new file mode 100644 index 0000000000000..66c6802c6b78f --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitProducers.cc @@ -0,0 +1,147 @@ +// CMSSW imports +#include "FWCore/Framework/interface/ESWatcher.h" +#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/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include // for std::setw +#include +#include + +// Alpaka imports +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDPutToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/Event.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" + +// includes for data formats +#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalRecHit/interface/HGCalRecHitHost.h" +#include "DataFormats/HGCalRecHit/interface/alpaka/HGCalRecHitDevice.h" + +// includes for size, calibration, and configuration parameters +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/alpaka/HGCalRecHitCalibrationAlgorithms.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using namespace cms::alpakatools; + + class HGCalRecHitsProducer : public stream::EDProducer<> { + public: + explicit HGCalRecHitsProducer(const edm::ParameterSet&); + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + void produce(device::Event&, device::EventSetup const&) override; + edm::ESWatcher calibWatcher_; + edm::ESWatcher configWatcher_; + const edm::EDGetTokenT digisToken_; + device::ESGetToken calibToken_; + device::ESGetToken configToken_; + const device::EDPutToken recHitsToken_; + const HGCalRecHitCalibrationAlgorithms calibrator_; + int n_hits_scale; + }; + + HGCalRecHitsProducer::HGCalRecHitsProducer(const edm::ParameterSet& iConfig) + : digisToken_{consumes(iConfig.getParameter("digis"))}, + calibToken_{esConsumes(iConfig.getParameter("calibSource"))}, + configToken_{esConsumes(iConfig.getParameter("configSource"))}, + recHitsToken_{produces()}, + calibrator_{iConfig.getParameter("n_blocks"), iConfig.getParameter("n_threads")}, + n_hits_scale{iConfig.getParameter("n_hits_scale")} {} + + void HGCalRecHitsProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("digis", edm::InputTag("hgcalDigis", "DIGI", "TEST")); + desc.add("calibSource", edm::ESInputTag{})->setComment("Label for calibration parameters"); + desc.add("configSource", edm::ESInputTag{})->setComment("Label for ROC configuration parameters"); + desc.add("n_blocks", -1); + desc.add("n_threads", -1); + desc.add("n_hits_scale", -1); + descriptions.addWithDefaultLabel(desc); + } + + void HGCalRecHitsProducer::produce(device::Event& iEvent, device::EventSetup const& iSetup) { + auto queue = iEvent.queue(); + + // Read digis + auto const& deviceCalibParamProvider = iSetup.getData(calibToken_); + auto const& deviceConfigParamProvider = iSetup.getData(configToken_); + auto const& hostDigisIn = iEvent.get(digisToken_); + + //printout new conditions if available + LogDebug("HGCalCalibrationParameter").log([&](auto& log) { + if (calibWatcher_.check(iSetup)) { + for (int i = 0; i < deviceConfigParamProvider.view().metadata().size(); i++) { + log << "gain = " << deviceConfigParamProvider.view()[i].gain() << "\n"; + } + } + }); + LogDebug("HGCalCalibrationParameter").log([&](auto& log) { + if (calibWatcher_.check(iSetup)) { + for (int i = 0; i < deviceCalibParamProvider.view().metadata().size(); i++) { + log << "idx = " << i << ", " + << "ADC_ped = " << deviceCalibParamProvider.view()[i].ADC_ped() << ", " + << "CM_slope = " << deviceCalibParamProvider.view()[i].CM_slope() << ", " + << "CM_ped = " << deviceCalibParamProvider.view()[i].CM_ped() << ", " + << "BXm1_slope = " << deviceCalibParamProvider.view()[i].BXm1_slope() << ", " << std::endl; + } + } + }); + + int oldSize = hostDigisIn.view().metadata().size(); + int newSize = oldSize * n_hits_scale; + auto hostDigis = HGCalDigiHost(newSize, queue); + // TODO: replace with memcp ? + for (int i = 0; i < newSize; i++) { + //hostDigis.view()[i].electronicsId() = hostDigisIn.view()[i%oldSize].electronicsId(); + hostDigis.view()[i].tctp() = hostDigisIn.view()[i % oldSize].tctp(); + hostDigis.view()[i].adcm1() = hostDigisIn.view()[i % oldSize].adcm1(); + hostDigis.view()[i].adc() = hostDigisIn.view()[i % oldSize].adc(); + hostDigis.view()[i].tot() = hostDigisIn.view()[i % oldSize].tot(); + hostDigis.view()[i].toa() = hostDigisIn.view()[i % oldSize].toa(); + hostDigis.view()[i].cm() = hostDigisIn.view()[i % oldSize].cm(); + hostDigis.view()[i].flags() = hostDigisIn.view()[i % oldSize].flags(); + //LogDebug("HGCalCalibrationParameter") + // << "idx=" << i << ", elecId=" << hostDigis.view()[i].electronicsId() + // << ", cm=" << hostDigis.view()[i].cm() << std::endl; + } + LogDebug("HGCalRecHitsProducer") << "Loaded host digis: " << hostDigis.view().metadata().size(); //<< std::endl; + + LogDebug("HGCalRecHitsProducer") << "\n\nINFO -- calling calibrate method"; //<< std::endl; + +#ifdef EDM_ML_DEBUG + alpaka::wait(queue); + auto start = std::chrono::high_resolution_clock::now(); +#endif + + auto recHits = calibrator_.calibrate(queue, hostDigis, deviceCalibParamProvider, deviceConfigParamProvider); + alpaka::wait(queue); + +#ifdef EDM_ML_DEBUG + auto stop = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = stop - start; + LogDebug("HGCalRecHitsProducer") << "Time spent calibrating: " << elapsed.count(); //<< std::endl; +#endif + + LogDebug("HGCalRecHitsProducer") << "\n\nINFO -- storing rec hits in the event"; //<< std::endl; + iEvent.emplace(recHitsToken_, std::move(*recHits)); + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +// define this as a plug-in +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(HGCalRecHitsProducer); diff --git a/RecoLocalCalo/HGCalRecAlgos/test/BuildFile.xml b/RecoLocalCalo/HGCalRecAlgos/test/BuildFile.xml index b805b2688fef0..41dd9ead8bfd2 100644 --- a/RecoLocalCalo/HGCalRecAlgos/test/BuildFile.xml +++ b/RecoLocalCalo/HGCalRecAlgos/test/BuildFile.xml @@ -1,8 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/RecoLocalCalo/HGCalRecAlgos/test/alpaka/TestHGCalRecHitESProducers.cc b/RecoLocalCalo/HGCalRecAlgos/test/alpaka/TestHGCalRecHitESProducers.cc new file mode 100644 index 0000000000000..192027d7a7775 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/test/alpaka/TestHGCalRecHitESProducers.cc @@ -0,0 +1,139 @@ +// Author: Izaak Neutelings (March 2024) +// Based on: https://github.com/CMS-HGCAL/cmssw/blob/hgcal-condformat-HGCalNANO-13_2_0_pre3_linearity/RecoLocalCalo/HGCalRecAlgos/plugins/alpaka/HGCalRecHitProducer.cc +#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/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDPutToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/Event.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" +#include // for std::setw +#include + +// includes for size, calibration, and configuration parameters +#include "FWCore/Framework/interface/ESWatcher.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalCalibrationParameterHost.h" +#include "CondFormats/HGCalObjects/interface/alpaka/HGCalCalibrationParameterDevice.h" // also for HGCalConfigParamDevice + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using namespace cms::alpakatools; + + class TestHGCalRecHitESProducers : public stream::EDProducer<> { + public: + explicit TestHGCalRecHitESProducers(const edm::ParameterSet&); + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + void produce(device::Event&, device::EventSetup const&) override; + void beginRun(edm::Run const&, edm::EventSetup const&) override; + edm::ESWatcher configWatcher_; + edm::ESGetToken indexerToken_; + edm::ESGetToken configToken_; + device::ESGetToken configParamToken_; + device::ESGetToken calibParamToken_; + }; + + TestHGCalRecHitESProducers::TestHGCalRecHitESProducers(const edm::ParameterSet& iConfig) { + std::cout << "TestHGCalRecHitESProducers::TestHGCalRecHitESProducers" << std::endl; + indexerToken_ = esConsumes(iConfig.getParameter("indexSource")); + configToken_ = esConsumes(iConfig.getParameter("configSource")); + configParamToken_ = esConsumes(iConfig.getParameter("configParamSource")); + calibParamToken_ = esConsumes(iConfig.getParameter("calibParamSource")); + } + + void TestHGCalRecHitESProducers::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("indexSource", edm::ESInputTag{})->setComment("Label for module indexer to set SoA size"); + desc.add("configSource", edm::ESInputTag{})->setComment("Label for HGCal configuration for unpacking raw data"); + desc.add("configParamSource", edm::ESInputTag{}) + ->setComment("Label for ROC configuration parameters for calibrations"); + desc.add("calibParamSource", edm::ESInputTag{})->setComment("Label for calibration parameters"); + descriptions.addWithDefaultLabel(desc); + } + + void TestHGCalRecHitESProducers::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) { + std::cout << "TestHGCalRecHitESProducers::beginRun" << std::endl; + } + + static std::string int2hex(int value) { + std::stringstream stream; + stream << "0x" << std::hex << value; + return stream.str(); + } + + void TestHGCalRecHitESProducers::produce(device::Event& iEvent, device::EventSetup const& iSetup) { + std::cout << "TestHGCalRecHitESProducers::produce" << std::endl; + auto queue = iEvent.queue(); + auto const& moduleMap = iSetup.getData(indexerToken_); + auto const& config = iSetup.getData(configToken_); // HGCalConfiguration + auto const& configParamDevice = iSetup.getData(configParamToken_); + //printf("TestHGCalRecHitESProducers::produce: time to load configParamDevice from config ESProducers: %f seconds\n", duration(start,now())); + auto const& calibParamDevice = iSetup.getData(calibParamToken_); + //printf("TestHGCalRecHitESProducers::produce: time to load calibParamDevice from calib ESProducers: %f seconds\n", duration(start,now())); + + // Check if there are new conditions and read them + if (configWatcher_.check(iSetup)) { + std::cout << "TestHGCalRecHitESProducers::produce: moduleMap.getMaxDataSize()=" << moduleMap.getMaxDataSize() + << ", moduleMap.getMaxERxSize()=" << moduleMap.getMaxERxSize() << std::endl; + + // ESProducer for global HGCal configuration (structs) with header markers, etc. + auto nfeds = config.feds.size(); // number of FEDs + std::cout << "TestHGCalRecHitESProducers::produce: config=" << config << std::endl; + std::cout << "TestHGCalRecHitESProducers::produce: nfeds=" << nfeds << ", config=" << config << std::endl; + for (std::size_t fedid = 0; fedid < nfeds; ++fedid) { + auto fed = config.feds[fedid]; // HGCalFedConfig + auto nmods = fed.econds.size(); // number of ECON-Ds for this FED + std::cout << " fedid=" << fedid << ", nmods=" << nmods << ", passthroughMode=" << fed.mismatchPassthroughMode + << ", cbHeaderMarker=0x" << std::hex << fed.cbHeaderMarker << ", slinkHeaderMarker=0x" + << fed.slinkHeaderMarker << std::dec << std::endl; + std::cout << " modid nrocs headerMarker" << std::endl; + for (std::size_t modid = 0; modid < nmods; ++modid) { + auto mod = fed.econds[modid]; + auto nrocs = mod.rocs.size(); // number of ECON-Ds for this FED + std::cout << std::setw(7) << modid << std::setw(7) << nrocs << std::setw(14) << int2hex(mod.headerMarker) + << std::endl; + } + } + + // Alpaka ESProducer for SoA with configuration parameters with gains + int size = configParamDevice.view().metadata().size(); + std::cout << "TestHGCalRecHitESProducers::produce: device size=" << size << std::endl; + std::cout << " imod gain" << std::endl; + for (int imod = 0; imod < size; imod++) { + if (imod >= 250) + break; + std::cout << std::setw(6) << imod << std::setw(6) << uint32_t(configParamDevice.view()[imod].gain()) + << std::endl; + } + + // Alpaka ESProducer for SoA with calibration parameters with pedestals, etc. + size = calibParamDevice.view().metadata().size(); + std::cout << "TestHGCalRecHitESProducers::produce: device size=" << size << std::endl; + std::cout << " idx hex ADC_ped CM_slope CM_ped BXm1_slope" << std::endl; + for (int idx = 0; idx < size; idx++) { + if (idx >= 250) + break; + std::cout << std::setw(6) << idx << std::setw(7) << int2hex(idx) << std::dec << std::setw(12) + << calibParamDevice.view()[idx].ADC_ped() << std::setw(11) << calibParamDevice.view()[idx].CM_slope() + << std::setw(9) << calibParamDevice.view()[idx].CM_ped() << std::setw(13) + << calibParamDevice.view()[idx].BXm1_slope() << std::endl; + } + } + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +// define this as a plug-in +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(TestHGCalRecHitESProducers); diff --git a/RecoLocalCalo/HGCalRecAlgos/test/testHGCalRecHitESProducers_cfg.py b/RecoLocalCalo/HGCalRecAlgos/test/testHGCalRecHitESProducers_cfg.py new file mode 100644 index 0000000000000..cf4842733f788 --- /dev/null +++ b/RecoLocalCalo/HGCalRecAlgos/test/testHGCalRecHitESProducers_cfg.py @@ -0,0 +1,146 @@ +# Author: Izaak Neutelings (March 2023) +# Instructions: +# export SCRAM_ARCH="el9_amd64_gcc12" +# cmsrel CMSSW_14_1_0_pre4 +# cd CMSSW_14_1_0_pre4/src/ +# cmsenv +# git cms-merge-topic -u CMS-HGCAL:dev/hackathon_base_CMSSW_14_1_X +# git clone https://github.com/pfs/Geometry-HGCalMapping.git $CMSSW_BASE/src/Geometry/HGCalMapping/data +# git clone https://gitlab.cern.ch/hgcal-dpg/hgcal-comm.git HGCalCommissioning +# scram b -j8 +# cmsRun $CMSSW_BASE/src/RecoLocalCalo/HGCalRecAlgos/test/testHGCalRecHitESProducers_cfg.py +# Sources: +# https://github.com/CMS-HGCAL/cmssw/blob/hgcal-condformat-HGCalNANO-13_2_0_pre3/DPGAnalysis/HGCalTools/python/tb2023_cfi.py +# https://gitlab.cern.ch/hgcal-dpg/hgcal-comm/-/blob/master/SystemTestEventFilters/test/test_raw2reco.py +# https://github.com/CMS-HGCAL/cmssw/blob/dev/hackathon_base_CMSSW_14_1_0_pre0/SimCalorimetry/HGCalSimProducers/test/hgcalRealistiDigis_cfg.py +import os +import FWCore.ParameterSet.Config as cms + +# USER OPTIONS +from FWCore.ParameterSet.VarParsing import VarParsing +datadir = os.path.join(os.environ.get('CMSSW_BASE',''),"src/HGCalCommissioning/LocalCalibration/data") +options = VarParsing('standard') +options.register('geometry', 'Extended2026D94', VarParsing.multiplicity.singleton, VarParsing.varType.string, + info="geometry to use") +options.register('fedconfig',f"{datadir}/config_feds.json",mytype=VarParsing.varType.string, + info="Path to configuration (JSON format)") +options.register('modconfig',f"{datadir}/config_econds.json",mytype=VarParsing.varType.string, + info="Path to configuration (JSON format)") +options.register('params',f"{datadir}/level0_calib_params.json",mytype=VarParsing.varType.string, + info="Path to calibration parameters (JSON format)") +options.register('modules', + #"Geometry/HGCalMapping/data/ModuleMaps/modulelocator_test.txt", # test beam with six modules + #"Geometry/HGCalMapping/data/ModuleMaps/modulelocator_test_2mods.txt", # only first two modules, fedId=49 + "HGCalCommissioning/Configuration/data/ModuleMaps/modulelocator_test_2mods.txt", # fedId=0 + mytype=VarParsing.varType.string, + info="Path to module mapper. Absolute, or relative to CMSSW src directory") +options.register('sicells','Geometry/HGCalMapping/data/CellMaps/WaferCellMapTraces.txt',mytype=VarParsing.varType.string, + info="Path to Si cell mapper. Absolute, or relative to CMSSW src directory") +options.register('sipmcells','Geometry/HGCalMapping/data/CellMaps/channels_sipmontile.hgcal.txt',mytype=VarParsing.varType.string, + info="Path to SiPM-on-tile cell mapper. Absolute, or relative to CMSSW src directory") +options.parseArguments() +if len(options.files)==0: + options.files=['file:/eos/cms/store/group/dpg_hgcal/comm_hgcal/psilva/hackhathon/23234.103_TTbar_14TeV+2026D94Aging3000/step2.root'] + #options.files=['file:/eos/cms/store/group/dpg_hgcal/comm_hgcal/psilva/hackhathon/23234.103_TTbar_14TeV+2026D94Aging3000/step2.root'] + #options.files=['file:/afs/cern.ch/user/y/yumiao/public/HGCAL_Raw_Data_Handling/Data/Digis/testFakeDigisSoA.root'] + #options.files=['file:/home/hgcdaq00/CMSSW/data/23234.103_TTbar_14TeV+2026D94Aging3000/step2.root'] # on DAQ PC + #options.files=['file:/home/hgcdaq00/CMSSW/data/testFakeDigisSoA.root'] # on DAQ PC +print(f">>> Geometry: {options.geometry!r}") +print(f">>> Input files: {options.files!r}") +print(f">>> Module map: {options.modules!r}") +print(f">>> SiCell map: {options.sicells!r}") +print(f">>> SipmCell map: {options.sipmcells!r}") +print(f">>> FED config: {options.fedconfig!r}") +print(f">>> ECON-D config: {options.modconfig!r}") +print(f">>> Calib params: {options.params!r}") + +# PROCESS +from Configuration.Eras.Era_Phase2C17I13M9_cff import Phase2C17I13M9 as Era_Phase2 +process = cms.Process('TestHGCalRecHitESProducers',Era_Phase2) + +# GLOBAL TAG +from Configuration.AlCa.GlobalTag import GlobalTag +process.load("Configuration.StandardSequences.Services_cff") +process.load("Configuration.StandardSequences.MagneticField_cff") +process.load("Configuration.EventContent.EventContent_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') + +# INPUT +process.source = cms.Source( + "PoolSource", + fileNames = cms.untracked.vstring(options.files), + duplicateCheckMode = cms.untracked.string("noDuplicateCheck") +) +#process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) ) +process.maxEvents.input = 1 + +# MESSAGE LOGGER +process.load("FWCore.MessageService.MessageLogger_cfi") +process.MessageLogger.cerr.threshold = '' +process.MessageLogger.cerr.FwkReport.reportEvery = 500 + +# GEOMETRY +process.load(f"Configuration.Geometry.Geometry{options.geometry}Reco_cff") +process.load(f"Configuration.Geometry.Geometry{options.geometry}_cff") +#process.load('Geometry.HGCalMapping.hgCalMappingIndexESSource_cfi') # old +process.load('Geometry.HGCalMapping.hgCalMappingESProducer_cfi') +process.hgCalMappingESProducer.si = cms.FileInPath(options.sicells) +process.hgCalMappingESProducer.sipm = cms.FileInPath(options.sipmcells) +process.hgCalMappingESProducer.modules = cms.FileInPath(options.modules) + +# GLOBAL CONFIGURATION ESProducers (for unpacker) +#process.load("RecoLocalCalo.HGCalRecAlgos.HGCalConfigurationESProducer") +#process.load("RecoLocalCalo.HGCalRecAlgos.hgCalConfigurationESProducer_cfi") +process.hgcalConfigESProducer = cms.ESSource( # ESProducer to load configurations for unpacker + 'HGCalConfigurationESProducer', + fedjson=cms.string(options.fedconfig), # JSON with FED configuration parameters + modjson=cms.string(options.modconfig), # JSON with ECON-D configuration parameters + #passthroughMode=cms.int32(0), # ignore mismatch + #cbHeaderMarker=cms.int32(0x7f), # capture block + ##cbHeaderMarker=cms.int32(0x5f), # capture block + #slinkHeaderMarker=cms.int32(0x55), # S-link + ##slinkHeaderMarker=cms.int32(0x2a), # S-link + #econdHeaderMarker=cms.int32(0x154), # ECON-D + #charMode=cms.int32(1), + indexSource=cms.ESInputTag('hgCalMappingESProducer','') +) + +# CALIBRATIONS & CONFIGURATION Alpaka ESProducers +process.load('Configuration.StandardSequences.Accelerators_cff') +#process.load('HeterogeneousCore.AlpakaCore.ProcessAcceleratorAlpaka_cfi') +#process.load('HeterogeneousCore.CUDACore.ProcessAcceleratorCUDA_cfi') +process.hgcalConfigParamESProducer = cms.ESProducer( # ESProducer to load configurations parameters from YAML file, like gain + 'hgcalrechit::HGCalConfigurationESProducer@alpaka', + gain=cms.int32(1), # to switch between 80, 160, 320 fC calibration + #charMode=cms.int32(1), + indexSource=cms.ESInputTag('hgCalMappingESProducer','') +) +process.hgcalCalibParamESProducer = cms.ESProducer( # ESProducer to load calibration parameters from JSON file, like pedestals + 'hgcalrechit::HGCalCalibrationESProducer@alpaka', + filename=cms.string(options.params), + indexSource=cms.ESInputTag('hgCalMappingESProducer',''), + configSource=cms.ESInputTag(''), +) + +# MAIN PROCESS +process.testHGCalRecHitESProducers = cms.EDProducer( + 'TestHGCalRecHitESProducers@alpaka', + #'alpaka_cuda_async::TestHGCalRecHitProducer', # GPU + #'alpaka_serial_sync::TestHGCalRecHitProducer', # CPU + indexSource=cms.ESInputTag('hgCalMappingESProducer', ''), + configSource=cms.ESInputTag('hgcalConfigESProducer', ''), + configParamSource=cms.ESInputTag('hgcalConfigParamESProducer', ''), + calibParamSource=cms.ESInputTag('hgcalCalibParamESProducer', ''), +) +process.t = cms.Task(process.testHGCalRecHitESProducers) +process.p = cms.Path(process.t) + +# OUTPUT +process.output = cms.OutputModule( + 'PoolOutputModule', + fileName = cms.untracked.string(options.output), + #outputCommands = cms.untracked.vstring('drop *','keep *_*_*_REALDIGI') +) +process.output_path = cms.EndPath(process.output) + diff --git a/SimCalorimetry/HGCalSimAlgos/BuildFile.xml b/SimCalorimetry/HGCalSimAlgos/BuildFile.xml index 65dc8a1d21d58..15b3ce3cb838f 100644 --- a/SimCalorimetry/HGCalSimAlgos/BuildFile.xml +++ b/SimCalorimetry/HGCalSimAlgos/BuildFile.xml @@ -1,5 +1,6 @@ + diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulator.h similarity index 72% rename from EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h rename to SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulator.h index 175d03441e765..4bbe98ebe19c3 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h +++ b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulator.h @@ -1,10 +1,10 @@ -#ifndef EventFilter_HGCalRawToDigi_HGCalECONDEmulator_h -#define EventFilter_HGCalRawToDigi_HGCalECONDEmulator_h +#ifndef SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulator_h +#define SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulator_h #include -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h" -#include "EventFilter/HGCalRawToDigi/interface/SlinkTypes.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorParameters.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/SlinkTypes.h" namespace hgcal::econd { /// Pure virtual base class for a ECON-D event emulator implementation diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorInfo.h b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorInfo.h similarity index 92% rename from EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorInfo.h rename to SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorInfo.h index 745b93ea56e10..e18846e43b2eb 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorInfo.h +++ b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorInfo.h @@ -1,5 +1,5 @@ -#ifndef EventFilter_HGCalRawToDigi_HGCalECONDEmulatorInfo_h -#define EventFilter_HGCalRawToDigi_HGCalECONDEmulatorInfo_h +#ifndef SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulatorInfo_h +#define SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulatorInfo_h #include #include diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorParameters.h similarity index 88% rename from EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h rename to SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorParameters.h index 61b60e26a86dc..85049fa15813e 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h +++ b/SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorParameters.h @@ -1,5 +1,5 @@ -#ifndef EventFilter_HGCalRawToDigi_HGCalECONDEmulatorParameters_h -#define EventFilter_HGCalRawToDigi_HGCalECONDEmulatorParameters_h +#ifndef SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulatorParameters_h +#define SimCalorimetry_HGCalSimAlgos_HGCalECONDEmulatorParameters_h #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalRawDataPackingTools.h b/SimCalorimetry/HGCalSimAlgos/interface/HGCalRawDataPackingTools.h similarity index 90% rename from EventFilter/HGCalRawToDigi/interface/HGCalRawDataPackingTools.h rename to SimCalorimetry/HGCalSimAlgos/interface/HGCalRawDataPackingTools.h index cfe2d08f47552..7127a79c0280d 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalRawDataPackingTools.h +++ b/SimCalorimetry/HGCalSimAlgos/interface/HGCalRawDataPackingTools.h @@ -1,7 +1,7 @@ -#ifndef EventFilter_HGCalRawToDigi_HGCalRawDataPackingTools_h -#define EventFilter_HGCalRawToDigi_HGCalRawDataPackingTools_h +#ifndef SimCalorimetry_HGCalSimAlgos_HGCalRawDataPackingTools_h +#define SimCalorimetry_HGCalSimAlgos_HGCalRawDataPackingTools_h -#include "EventFilter/HGCalRawToDigi/interface/SlinkTypes.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/SlinkTypes.h" namespace hgcal { namespace econd { @@ -50,22 +50,12 @@ namespace hgcal { } // namespace econd namespace backend { - enum ECONDPacketStatus { - Normal = 0x0, - PayloadCRCError = 0x1, - EventIDMismatch = 0x2, - EBTimeout = 0x4, - BCIDOrbitIDMismatch = 0x5, - MainBufferOverflow = 0x6, - InactiveECOND = 0x7 - }; - /// builds the capture block header (see page 16 of "HGCAL BE DAQ firmware description") /// \return a vector of size 2 with the 2 32b words of the capture block header std::vector buildCaptureBlockHeader(uint32_t bunch_crossing, uint32_t event_counter, uint32_t orbit_counter, - const std::vector& econd_statuses); + const std::vector& econd_statuses); /// builds the slink frame header (128 bits header = 4 words) /// \return a vector with 4 32b words diff --git a/EventFilter/HGCalRawToDigi/interface/SlinkTypes.h b/SimCalorimetry/HGCalSimAlgos/interface/SlinkTypes.h similarity index 78% rename from EventFilter/HGCalRawToDigi/interface/SlinkTypes.h rename to SimCalorimetry/HGCalSimAlgos/interface/SlinkTypes.h index f84a79716eedd..3b872ff4d077a 100644 --- a/EventFilter/HGCalRawToDigi/interface/SlinkTypes.h +++ b/SimCalorimetry/HGCalSimAlgos/interface/SlinkTypes.h @@ -1,12 +1,12 @@ -#ifndef EventFilter_HGCalRawToDigi_SlinkTypes_h -#define EventFilter_HGCalRawToDigi_SlinkTypes_h +#ifndef SimCalorimetry_HGCalSimAlgos_SlinkTypes_h +#define SimCalorimetry_HGCalSimAlgos_SlinkTypes_h #include #include #include #include -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" namespace hgcal::econd { @@ -19,7 +19,7 @@ namespace hgcal::econd { /// parsed e-rx data struct ERxData { uint32_t cm0{0}, cm1{0}; - std::vector tctp; + std::vector tctp; // vector of hgcal::econd::ToTStatus std::vector adc, adcm, toa, tot; std::vector meta; ///< additional words accompanying the e-rx data uint32_t crc32{0}; diff --git a/EventFilter/HGCalRawToDigi/src/HGCalECONDEmulatorParameters.cc b/SimCalorimetry/HGCalSimAlgos/src/HGCalECONDEmulatorParameters.cc similarity index 96% rename from EventFilter/HGCalRawToDigi/src/HGCalECONDEmulatorParameters.cc rename to SimCalorimetry/HGCalSimAlgos/src/HGCalECONDEmulatorParameters.cc index 6f1f29eb553ea..3a3f300f768cf 100644 --- a/EventFilter/HGCalRawToDigi/src/HGCalECONDEmulatorParameters.cc +++ b/SimCalorimetry/HGCalSimAlgos/src/HGCalECONDEmulatorParameters.cc @@ -1,5 +1,5 @@ -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulatorParameters.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulatorParameters.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" using namespace hgcal::econd; diff --git a/EventFilter/HGCalRawToDigi/src/HGCalRawDataPackingTools.cc b/SimCalorimetry/HGCalSimAlgos/src/HGCalRawDataPackingTools.cc similarity index 94% rename from EventFilter/HGCalRawToDigi/src/HGCalRawDataPackingTools.cc rename to SimCalorimetry/HGCalSimAlgos/src/HGCalRawDataPackingTools.cc index 1a8b9c14c004c..40fcae46d26a6 100644 --- a/EventFilter/HGCalRawToDigi/src/HGCalRawDataPackingTools.cc +++ b/SimCalorimetry/HGCalSimAlgos/src/HGCalRawDataPackingTools.cc @@ -1,5 +1,5 @@ -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataPackingTools.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/HGCalRawDataPackingTools.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/Exception.h" @@ -161,11 +161,10 @@ uint32_t hgcal::econd::buildIdleWord(uint8_t bufStat, uint8_t err, uint8_t rr, u } // -std::vector hgcal::backend::buildCaptureBlockHeader( - uint32_t bunch_crossing, - uint32_t event_counter, - uint32_t orbit_counter, - const std::vector& econd_statuses) { +std::vector hgcal::backend::buildCaptureBlockHeader(uint32_t bunch_crossing, + uint32_t event_counter, + uint32_t orbit_counter, + const std::vector& econd_statuses) { if (econd_statuses.size() > 12) throw cms::Exception("HGCalEmulator") << "Invalid size for ECON-D statuses: " << econd_statuses.size() << "."; std::vector header(2, 0); @@ -185,9 +184,9 @@ std::vector hgcal::backend::buildSlinkHeader( std::vector header(4, 0); header[0] = (boe & hgcal::BACKEND_FRAME::SLINK_BOE_MASK) << hgcal::BACKEND_FRAME::SLINK_BOE_POS | (v & hgcal::BACKEND_FRAME::SLINK_V_MASK) << hgcal::BACKEND_FRAME::SLINK_V_POS | - ((global_event_id >> 41) & SLINK_GLOBAL_EVENTID_MSB_MASK) + ((global_event_id >> 41) & hgcal::BACKEND_FRAME::SLINK_GLOBAL_EVENTID_MSB_MASK) << hgcal::BACKEND_FRAME::SLINK_GLOBAL_EVENTID_MSB_POS; - header[1] = (global_event_id & SLINK_GLOBAL_EVENTID_LSB_MASK); + header[1] = (global_event_id & hgcal::BACKEND_FRAME::SLINK_GLOBAL_EVENTID_LSB_MASK); header[2] = (content_id & hgcal::BACKEND_FRAME::SLINK_CONTENTID_MASK) << hgcal::BACKEND_FRAME::SLINK_CONTENTID_POS; header[3] = (fed_id & hgcal::BACKEND_FRAME::SLINK_SOURCEID_MASK) << hgcal::BACKEND_FRAME::SLINK_SOURCEID_POS; diff --git a/EventFilter/HGCalRawToDigi/src/TrivialEmulator.cc b/SimCalorimetry/HGCalSimAlgos/src/TrivialEmulator.cc similarity index 72% rename from EventFilter/HGCalRawToDigi/src/TrivialEmulator.cc rename to SimCalorimetry/HGCalSimAlgos/src/TrivialEmulator.cc index 2d03dd362ad43..d511f2025ed5d 100644 --- a/EventFilter/HGCalRawToDigi/src/TrivialEmulator.cc +++ b/SimCalorimetry/HGCalSimAlgos/src/TrivialEmulator.cc @@ -1,5 +1,5 @@ -#include "EventFilter/HGCalRawToDigi/interface/HGCalECONDEmulator.h" -#include "EventFilter/HGCalRawToDigi/interface/HGCalRawDataDefinitions.h" +#include "SimCalorimetry/HGCalSimAlgos/interface/HGCalECONDEmulator.h" +#include "DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h" using namespace hgcal::econd; @@ -11,7 +11,7 @@ ECONDInput TrivialEmulator::next() { ERxData dummy_data{ .cm0 = 0x12, .cm1 = 0x34, - .tctp = std::vector(params_.num_channels_per_erx, static_cast(params_.default_totstatus)), + .tctp = std::vector(params_.num_channels_per_erx, static_cast(params_.default_totstatus)), .adc = std::vector(params_.num_channels_per_erx, 0), .adcm = std::vector(params_.num_channels_per_erx, 0), .toa = std::vector(params_.num_channels_per_erx, 0), diff --git a/SimCalorimetry/HGCalSimProducers/BuildFile.xml b/SimCalorimetry/HGCalSimProducers/BuildFile.xml index 6860254dcc3b5..6651a869bf93d 100644 --- a/SimCalorimetry/HGCalSimProducers/BuildFile.xml +++ b/SimCalorimetry/HGCalSimProducers/BuildFile.xml @@ -10,4 +10,4 @@ - + \ No newline at end of file diff --git a/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml b/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml index 7c684aac304c7..b98b39d968083 100644 --- a/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml +++ b/SimCalorimetry/HGCalSimProducers/plugins/BuildFile.xml @@ -1,9 +1,13 @@ - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file