diff --git a/CondCore/MTDPlugins/BuildFile.xml b/CondCore/MTDPlugins/BuildFile.xml new file mode 100644 index 0000000000000..a4512e924b035 --- /dev/null +++ b/CondCore/MTDPlugins/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/CondCore/MTDPlugins/src/plugin.cc b/CondCore/MTDPlugins/src/plugin.cc new file mode 100644 index 0000000000000..7a0093ae8bfe8 --- /dev/null +++ b/CondCore/MTDPlugins/src/plugin.cc @@ -0,0 +1,12 @@ +#include "CondCore/ESSources/interface/registration_macros.h" + +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" +#include "CondFormats/DataRecord/interface/BTLReadoutMapRcd.h" + +namespace { + struct initializeBtlReadoutMap { + void operator()(BTLReadoutMap& m) { m.initialize(); } + }; +} // namespace + +REGISTER_PLUGIN_INIT(BTLReadoutMapRcd, BTLReadoutMap, initializeBtlReadoutMap); diff --git a/CondFormats/DataRecord/interface/BTLReadoutMapRcd.h b/CondFormats/DataRecord/interface/BTLReadoutMapRcd.h new file mode 100644 index 0000000000000..9a5366ec8fcbc --- /dev/null +++ b/CondFormats/DataRecord/interface/BTLReadoutMapRcd.h @@ -0,0 +1,14 @@ +#ifndef CondFormats_DataRecord_BTLReadoutMapRcd_h +#define CondFormats_DataRecord_BTLReadoutMapRcd_h + +#include "FWCore/Framework/interface/EventSetupRecordImplementation.h" +#include "Geometry/Records/interface/MTDGeometryRecord.h" +#include "Geometry/Records/interface/MTDTopologyRcd.h" + +#include "FWCore/Utilities/interface/mplVector.h" + +class BTLReadoutMapRcd + : public edm::eventsetup::DependentRecordImplementation > { +}; +#endif diff --git a/CondFormats/DataRecord/src/BTLReadoutMapRcd.cc b/CondFormats/DataRecord/src/BTLReadoutMapRcd.cc new file mode 100644 index 0000000000000..6402fc1203223 --- /dev/null +++ b/CondFormats/DataRecord/src/BTLReadoutMapRcd.cc @@ -0,0 +1,4 @@ +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" +#include "CondFormats/DataRecord/interface/BTLReadoutMapRcd.h" + +EVENTSETUP_RECORD_REG(BTLReadoutMapRcd); diff --git a/CondFormats/MTDObjects/BuildFile.xml b/CondFormats/MTDObjects/BuildFile.xml new file mode 100644 index 0000000000000..563f83e517c99 --- /dev/null +++ b/CondFormats/MTDObjects/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/CondFormats/MTDObjects/interface/BTLElectronicsId.h b/CondFormats/MTDObjects/interface/BTLElectronicsId.h new file mode 100644 index 0000000000000..499a0022132ac --- /dev/null +++ b/CondFormats/MTDObjects/interface/BTLElectronicsId.h @@ -0,0 +1,60 @@ +#ifndef CondFormats_MTDObjects_BTLElectronicsId_h +#define CondFormats_MTDObjects_BTLElectronicsId_h + +#include "CondFormats/Serialization/interface/Serializable.h" + +#include +#include + +class BTLElectronicsId { +public: + // Bit layout: + // + // 0 - 4 : channelId 0..31 (5 bits) + // 5 - 9 : eLinkId 0..23 (5 bits) + // 10 - 16 : hsLinkId 0..127 (7 bits) + // 17 - 29 : fedId ? (13 bits) + // 30 - 31 : free for now + + static constexpr uint32_t kChannelMask = 0x1F; // 5 bits + static constexpr uint32_t kELinkMask = 0x1F; // 5 bits + static constexpr uint32_t kHSLinkMask = 0x7F; // 7 bits + static constexpr uint32_t kFEDMask = 0x1FFF; // 13 bits + + static constexpr unsigned kChannelShift = 0; + static constexpr unsigned kELinkShift = 5; + static constexpr unsigned kHSLinkShift = 10; + static constexpr unsigned kFEDShift = 17; + + /** Default constructor **/ + BTLElectronicsId(); + + /** Constructor from rawId **/ + explicit BTLElectronicsId(uint32_t rawid); + + /** Constructor from (FED id, HS-link id, e-link id, tofhir channel id) **/ + BTLElectronicsId(int fedId, // sLinkId + int hsLinkId, + int eLinkId, + int channelId); + + /// Accessors + int fedId() const { return (rawid_ >> kFEDShift) & kFEDMask; }; + int hsLinkId() const { return (rawid_ >> kHSLinkShift) & kHSLinkMask; }; + int eLinkId() const { return (rawid_ >> kELinkShift) & kELinkMask; }; + int channelId() const { return (rawid_ >> kChannelShift) & kChannelMask; } + + uint32_t rawId() const { return rawid_; }; + + bool operator==(const BTLElectronicsId&) const; + bool operator!=(const BTLElectronicsId&) const; + +private: + uint32_t rawid_ = 0; + + COND_SERIALIZABLE; +}; + +std::ostream& operator<<(std::ostream&, const BTLElectronicsId&); + +#endif diff --git a/CondFormats/MTDObjects/interface/BTLReadoutMap.h b/CondFormats/MTDObjects/interface/BTLReadoutMap.h new file mode 100644 index 0000000000000..3a69e30101b63 --- /dev/null +++ b/CondFormats/MTDObjects/interface/BTLReadoutMap.h @@ -0,0 +1,63 @@ +#ifndef CondFormats_MTDObjects_BTLReadoutMap_h +#define CondFormats_MTDObjects_BTLReadoutMap_h + +#include +#include + +#include "DataFormats/ForwardDetId/interface/BTLDetId.h" +#include "CondFormats/MTDObjects/interface/BTLElectronicsId.h" +#include "CondFormats/Serialization/interface/Serializable.h" + +//------------------------------------------------------------ +// Electronics IDs corresponding to the two sides of one crystal +//------------------------------------------------------------ +struct BTLElectronicsIdPair { + BTLElectronicsId minus; + BTLElectronicsId plus; + + COND_SERIALIZABLE; +}; + +// ------------------------------------------------------------ +// Readout map: BTLDetId <-> BTLElectronicsId +// ------------------------------------------------------------ +class BTLReadoutMap { +public: + BTLReadoutMap(); + virtual ~BTLReadoutMap(); + + // ---------------------------- + // Fill interface - inserts a new record in the readout map + // ---------------------------- + void add(const BTLDetId& detId, const BTLElectronicsIdPair& elecIds); + + // ---------------------------- + // Forward lookup: DetId -> electronics + // ---------------------------- + BTLElectronicsIdPair getElectronicsId(const BTLDetId& detId) const; + + // ---------------------------- + // Reverse lookup: electronics -> DetId + // ---------------------------- + BTLDetId getDetId(const BTLElectronicsId& elecId) const; + + // ---------------------------- + // Utilities + // ---------------------------- + void initialize(); + + void clear(); + + int size() const { return detToElec_.size(); }; + +private: + // forward mapping + std::unordered_map detToElec_; + + // reverse mapping (packed electronics key -> detid) + std::unordered_map elecToDet_ COND_TRANSIENT; + + COND_SERIALIZABLE; +}; + +#endif diff --git a/CondFormats/MTDObjects/src/BTLElectronicsId.cc b/CondFormats/MTDObjects/src/BTLElectronicsId.cc new file mode 100644 index 0000000000000..a582dc1ef3753 --- /dev/null +++ b/CondFormats/MTDObjects/src/BTLElectronicsId.cc @@ -0,0 +1,35 @@ +#include "CondFormats/MTDObjects/interface/BTLElectronicsId.h" + +#include + +// ------------------------------------------------------------ +// Constructors +// ------------------------------------------------------------ +BTLElectronicsId::BTLElectronicsId() : rawid_(0) {} + +BTLElectronicsId::BTLElectronicsId(uint32_t rawid) : rawid_(rawid) {} + +BTLElectronicsId::BTLElectronicsId(int fed, int hsLink, int eLink, int channel) { + rawid_ = (static_cast(fed) << kFEDShift) | (static_cast(hsLink) << kHSLinkShift) | + (static_cast(eLink) << kELinkShift) | (static_cast(channel) << kChannelShift); +} + +// ------------------------------------------------------------ +// Comparison operators +// ------------------------------------------------------------ + +bool BTLElectronicsId::operator==(const BTLElectronicsId& other) const { return rawid_ == other.rawid_; } + +bool BTLElectronicsId::operator!=(const BTLElectronicsId& other) const { return rawid_ != other.rawid_; } + +// ------------------------------------------------------------ +// Stream operator +// ------------------------------------------------------------ + +std::ostream& operator<<(std::ostream& os, const BTLElectronicsId& id) { + os << "BTLElectronicsId: " + << "rawId = " << static_cast(id.rawId()) << ", FED Id = " << id.fedId() << ", HS-link = " << id.hsLinkId() + << ", e-link = " << id.eLinkId() << ", TOFHIR channel Id = " << id.channelId(); + + return os; +} diff --git a/CondFormats/MTDObjects/src/BTLReadoutMap.cc b/CondFormats/MTDObjects/src/BTLReadoutMap.cc new file mode 100644 index 0000000000000..1a2b28c66599f --- /dev/null +++ b/CondFormats/MTDObjects/src/BTLReadoutMap.cc @@ -0,0 +1,100 @@ +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" + +#include +#include + +BTLReadoutMap::BTLReadoutMap() {} + +BTLReadoutMap::~BTLReadoutMap() {} + +// ------------------------------------------------------------------ +// Initialize - to build inverse map which is not stored persistently +// ------------------------------------------------------------------ +void BTLReadoutMap::initialize() { + elecToDet_.clear(); + + for (const auto& entry : detToElec_) { + const uint32_t detId = entry.first; + const BTLElectronicsIdPair& elecIds = entry.second; + + auto ret = elecToDet_.emplace(elecIds.minus.rawId(), detId); + if (!ret.second) { + throw cms::Exception("BTLReadoutMap::initialize()") << "Duplicate BTLElectronicsId (minus side)" << std::endl; + } + + ret = elecToDet_.emplace(elecIds.plus.rawId(), detId); + if (!ret.second) { + throw cms::Exception("BTLReadoutMap::initialize()") << "Duplicate BTLElectronicsId (plus side)" << std::endl; + } + } +} + +// ------------------------------------------------------------ +// Add full 2-channel mapping +// ------------------------------------------------------------ +void BTLReadoutMap::add(const BTLDetId& detId, const BTLElectronicsIdPair& elecIds) { + const uint32_t detKey = detId.rawId(); + + // ---------------------------- + // Forward: det -> 2 channels + // ---------------------------- + if (detToElec_.find(detKey) != detToElec_.end()) { + throw cms::Exception("BTLReadoutMap::add()") << "Duplicate BTLDetId entry" << std::endl; + } + + detToElec_[detKey] = elecIds; + + // ---------------------------- + // Reverse: each channel -> det + // ---------------------------- + + // -- minus side + const uint32_t minusKey = elecIds.minus.rawId(); + if (elecToDet_.find(minusKey) != elecToDet_.end()) { + throw cms::Exception("BTLReadoutMap::add()") << "Duplicate BTLElectronicsId entry (minus side): " << elecIds.minus; + } + elecToDet_[minusKey] = detKey; + + // -- plus side + const uint32_t plusKey = elecIds.plus.rawId(); + if (elecToDet_.find(plusKey) != elecToDet_.end()) { + throw cms::Exception("BTLReadoutMap::add()") << "Duplicate BTLElectronicsId entry (plus side): " << elecIds.plus; + } + elecToDet_[plusKey] = detKey; +} + +// ------------------------------------------------------------ +// Forward lookup +// ------------------------------------------------------------ +BTLElectronicsIdPair BTLReadoutMap::getElectronicsId(const BTLDetId& detId) const { + const auto it = detToElec_.find(detId.rawId()); + + if (it == detToElec_.end()) { + throw cms::Exception("BTLReadoutMap::getElectronicsId") << "BTLDetId " << detId.rawId() << " not found! "; + } + + return it->second; +} + +// ------------------------------------------------------------ +// Reverse lookup +// ------------------------------------------------------------ +BTLDetId BTLReadoutMap::getDetId(const BTLElectronicsId& elecId) const { + const auto it = elecToDet_.find(elecId.rawId()); + + if (it == elecToDet_.end()) { + throw cms::Exception("BTLReadoutMap::getElectronicsId") << "BTLElectronicsId " << elecId.rawId() << " not found! "; + } + + return BTLDetId(it->second); +} + +// ------------------------------------------------------------ +// clear +// ------------------------------------------------------------ +void BTLReadoutMap::clear() { + detToElec_.clear(); + elecToDet_.clear(); +} diff --git a/CondFormats/MTDObjects/src/T_EventSetup_BTLReadoutMap.cc b/CondFormats/MTDObjects/src/T_EventSetup_BTLReadoutMap.cc new file mode 100644 index 0000000000000..2f0fb029587cb --- /dev/null +++ b/CondFormats/MTDObjects/src/T_EventSetup_BTLReadoutMap.cc @@ -0,0 +1,4 @@ +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(BTLReadoutMap); diff --git a/CondFormats/MTDObjects/src/classes.h b/CondFormats/MTDObjects/src/classes.h new file mode 100644 index 0000000000000..61873d70d0403 --- /dev/null +++ b/CondFormats/MTDObjects/src/classes.h @@ -0,0 +1,11 @@ +#include "CondFormats/MTDObjects/interface/BTLElectronicsId.h" +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" + +namespace CondFormats_MTDObjects { + struct dictionary { + BTLElectronicsId electronicsId; + BTLElectronicsIdPair electronicsIdPair; + BTLReadoutMap readoutMap; + std::unordered_map detToElec; + }; +} // namespace CondFormats_MTDObjects diff --git a/CondFormats/MTDObjects/src/classes_def.xml b/CondFormats/MTDObjects/src/classes_def.xml new file mode 100644 index 0000000000000..e1b596c342449 --- /dev/null +++ b/CondFormats/MTDObjects/src/classes_def.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/CondFormats/MTDObjects/src/headers.h b/CondFormats/MTDObjects/src/headers.h new file mode 100644 index 0000000000000..69b2fea418b5d --- /dev/null +++ b/CondFormats/MTDObjects/src/headers.h @@ -0,0 +1,2 @@ +#include "CondFormats/MTDObjects/interface/BTLElectronicsId.h" +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" diff --git a/EventFilter/MTDRawToDigi/BuildFile.xml b/EventFilter/MTDRawToDigi/BuildFile.xml new file mode 100644 index 0000000000000..634b08d47a807 --- /dev/null +++ b/EventFilter/MTDRawToDigi/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h b/EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h new file mode 100644 index 0000000000000..6155eeffd7289 --- /dev/null +++ b/EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h @@ -0,0 +1,73 @@ +#ifndef EventFilter_MTDRawToDigi_BTLElectronicsMapping_h +#define EventFilter_MTDRawToDigi_BTLElectronicsMapping_h + +#include +#include + +#include "DataFormats/ForwardDetId/interface/BTLDetId.h" +#include "EventFilter/MTDRawToDigi/interface/BTLElectronicsSpecs.h" + +/** + * Helper functions for BTL electronics/DAQ mapping + */ + +class BTLElectronicsMapping { +public: + /** Default constructor */ + BTLElectronicsMapping(); + + // ------------------------------------------------------------------ + // SiPM channel / TOFHIR channel mapping helper functions + // ------------------------------------------------------------------ + /** \brief BTL TOFHIR channel mapping with crystal BTLDetId + Convention: + SiPMside 0 == Minus Side + SiPMside 1 == Plus Side + */ + + // -- Get SiPM Channel number from crystal + int SiPMCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) const; + int SiPMCh(BTLDetId det, uint32_t SiPMSide) const; + int SiPMCh(uint32_t rawID, uint32_t SiPMSide) const; + + // -- Get TOFHIR Channel number from crystal + int TOFHIRCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) const; + int TOFHIRCh(BTLDetId det, uint32_t SiPMSide) const; + int TOFHIRCh(uint32_t rawID, uint32_t SiPMSide) const; + + // -- Returns TOFHIR ASIC number in construction database + int TOFHIRASIC(uint32_t dmodule, uint32_t smodCopy) const; + int TOFHIRASIC(BTLDetId det) const; + int TOFHIRASIC(uint32_t rawID) const; + + // ------------------------------------------------------------------ + // E-link mapping helper functions + // ------------------------------------------------------------------ + + // -- Get the e-link for a given SM + int elinkFromSM(uint32_t dmodule, uint32_t smodCopy, int lpgbt_id = 0) const; + int elink(BTLDetId det, int lpgbt_id = 0) const; + int elink(uint32_t rawID, int lpgbt_id = 0) const; + + // ------------------------------------------------------------------ + // HS-link mapping helper functions + // ------------------------------------------------------------------ + // -- Get the HS-link corresponding to a given RU/CC in a tray + int opticalTxPosition(uint32_t tray, int optTxCh) const; + int hslinkFromRU(uint32_t runit, uint32_t tray, int lpgbt_id = 0) const; + int hslink(BTLDetId det, int lpgbt_id = 0) const; + int hslink(uint32_t rawID, int lpgbt_id = 0) const; + + // ------------------------------------------------------------------ + // S-link mapping + // ------------------------------------------------------------------ + /** one S-link corresponds to a group of 6 trays. One S-link = One FEDId **/ + // -- Get the S-link for a given tray + int slinkFromTray(uint32_t tray, uint32_t zside) const; + int slink(BTLDetId det) const; + int slink(uint32_t rawID) const; + +private: +}; + +#endif diff --git a/EventFilter/MTDRawToDigi/interface/BTLElectronicsSpecs.h b/EventFilter/MTDRawToDigi/interface/BTLElectronicsSpecs.h new file mode 100644 index 0000000000000..23b0e71a9ea1e --- /dev/null +++ b/EventFilter/MTDRawToDigi/interface/BTLElectronicsSpecs.h @@ -0,0 +1,121 @@ +#ifndef EventFilter_MTDRawToDigi_BTLElectronicsSpecs_h +#define EventFilter_MTDRawToDigi_BTLElectronicsSpecs_h + +#include +#include +#include + +#include "DataFormats/ForwardDetId/interface/BTLDetId.h" + +/** + * Lookup tables - Pure firmware / DAQ encoding specifications. + * + */ + +namespace BTLElectronicsSpecs { + + // ============================================================ + // TOFHIR channel ID mapping + // ============================================================ + + // Map SiPM Channel to crystal bars for Forward module orientation + static constexpr std::array SiPMChannelMapFW{ + {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}; + + // Map SiPM Channel to crystal bars for Backward module orientation + static constexpr std::array SiPMChannelMapBW{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16}}; + + // Map TOFHIR Channel to SiPM Channel + static constexpr std::array THChannelMap{ + {4, 1, 0, 3, 2, 6, 7, 9, 5, 11, 8, 12, 10, 14, 15, 13, + 17, 16, 18, 19, 20, 23, 21, 26, 22, 27, 28, 31, 30, 24, 25, 29}}; + + // ============================================================ + // E-LINK mapping + // ============================================================ + /** E-LINK identifies which TOFHIR/SM within a CC. The mapping depends if lpgbt L0 or L1 is used. Default is L0. **/ + /** Ref: https://gitlab.cern.ch/btl-commissioning/mtd_daq/-/blob/tif_new_s1p2/src/mtd_daq/configurator/mappings.py?ref_type=heads#L79-130 */ + + static constexpr std::array, BTLDetId::kDModulesPerRU * 2> ELINK_to_FE_mapping_L0{{ + {7, 1}, // e-link 0: {DM 7, chipId 1} + {7, 0}, // e-link 1: {DM 7, chipId 0} + {3, 1}, {3, 0}, {2, 1}, {2, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {5, 0}, {5, 1}, {4, 1}, {4, 0}, + {8, 0}, {9, 1}, {9, 0}, {8, 1}, {10, 0}, {10, 1}, {11, 1}, {11, 0}, {6, 1}, {6, 0} // e-link 23: {DM 6, chipId 0} + }}; + + static constexpr std::array, BTLDetId::kDModulesPerRU * 2> ELINK_to_FE_mapping_L1{{ + {6, 1}, // e-link 0: {DM 6, chipId 1} + {3, 1}, // e-link 1: {DM 3, chipId 1} + {7, 0}, {7, 1}, {3, 0}, {6, 0}, {2, 1}, {2, 0}, {1, 0}, {1, 1}, {0, 0}, {0, 1}, {5, 1}, {5, 0}, + {4, 0}, {4, 1}, {9, 1}, {9, 0}, {8, 0}, {8, 1}, {10, 0}, {10, 1}, {11, 0}, {11, 1} // e-link 23: {DM 11, chipId 1} + }}; + + // ELINK Reverse mapping: given an FE/DM (0-11) and a ChipId (0-1), find the corresponding e-link + static constexpr auto buildFEtoElinkMapping = [](auto const& mapping) { + std::array, BTLDetId::kDModulesPerRU> tmp{}; // pair is (DM, chipId), there are 12 pairs. + for (auto& row : tmp) + row.fill(-1); // initialize to -1 + for (unsigned int elink = 0; elink < BTLDetId::kDModulesPerRU * 2; ++elink) { + tmp[mapping[elink].first][mapping[elink].second] = static_cast(elink); + } + return tmp; + }; + + static constexpr auto FE_to_ELINK_mapping_L0 = buildFEtoElinkMapping(ELINK_to_FE_mapping_L0); + static constexpr auto FE_to_ELINK_mapping_L1 = buildFEtoElinkMapping(ELINK_to_FE_mapping_L1); + + // ============================================================ + // HS-LINK mapping + // ============================================================ + // ** HS-link = link CC/RU to Serenity **/ + // Mapping of FPGA Tx port number (= HS-link) to optical Tx channels provided by O. Sahin. + // Note: this mapping is not strictly sequential + // There are 72 = 6 x 12 hs-links (now from 4 to 75) in blocks of 12. Each block will correspond to one tray. + // Within each block: + // Opt Tx 0, 2, 4, 6, 8, 10 --> correspond to CC 0,1,2,3,4,5 for LPGBT0 + // Opt Tx 1, 3, 5, 7, 9, 11 --> correspond to CC 0,1,2,3,4,5 for LPGBT1 + + // Define an array of 12 elements, each element is the optical Tx channel Id (this depends on the FF). + // For the first block (FF_N5), channel ids of the optical tx are reversed. + // Each optical Tx channel Id maps to a CC/RU + static constexpr std::array optTxCh_n5 = { + 1, 3, 5, 0, 2, 4, 6, 8, 10, 7, 9, 11}; // 12 = 6 RUs x 2 LPGBTs + static constexpr std::array optTxCh_common = { + 11, 9, 7, 10, 8, 6, 4, 2, 0, 5, 3, 1}; // 12 = 6 RUs x 2 LPGBTs + + // ============================================================ + // DAQ constants + // ============================================================ + static constexpr uint32_t kHSLinksNum = 72; // number of HS links: in each Serenity 6 trays x 12 links + static constexpr uint32_t kHSLinksOffset = 4; // offset (HS link Ids start from 4 (0-3 reserved) + static constexpr uint32_t kFirstFEDId = 0; // arbitrary for now + + static constexpr auto OptTx_map = []() { + std::array tmp; + tmp.fill(-1); + for (unsigned int i = 0; i < kHSLinksNum / 12; i++) { + for (int j = 0; j < 12; j++) { + int hslink_id = kHSLinksOffset + i * 12 + j; + tmp[hslink_id] = (i == 0) ? optTxCh_n5[j] : optTxCh_common[j]; + } + } + return tmp; + }(); + + // Build inverse mapping + static constexpr auto tx_to_index = [](const std::array& p) { + std::array inv{}; + inv.fill(-1); + for (int i = 0; i < 12; ++i) + inv[p[i]] = i; + return inv; + }; + static constexpr auto tx_inv_n5 = tx_to_index(optTxCh_n5); + static constexpr auto tx_inv_common = tx_to_index(optTxCh_common); + +} // namespace BTLElectronicsSpecs + +#endif diff --git a/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.cc b/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.cc new file mode 100644 index 0000000000000..1674f7b25292e --- /dev/null +++ b/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.cc @@ -0,0 +1,81 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.h" +#include "EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h" + +// ------------------------------------------------------------ +// +BTLReadoutMapESProducer::BTLReadoutMapESProducer(const edm::ParameterSet& iConfig) { + auto cc = setWhatProduced(this, &BTLReadoutMapESProducer::produce); + + geomToken_ = cc.consumes(); + topoToken_ = cc.consumes(); +} + +// ----------------------------------------------------------------------------- +// +BTLReadoutMapESProducer::~BTLReadoutMapESProducer() {} + +// ------------------------------------------------------------ +// +std::unique_ptr BTLReadoutMapESProducer::produce(const BTLReadoutMapRcd& iRecord) { + const auto& geom = iRecord.get(geomToken_); + const auto& topo = iRecord.get(topoToken_); + auto btlCrysLayout = MTDTopologyMode::crysLayoutFromTopoMode(topo.getMTDTopologyMode()); + + // -- Readout map defined only for CrysLayout::v4 - If not v4, returns empty map + if (static_cast(btlCrysLayout) < static_cast(BTLDetId::CrysLayout::v4)) { + edm::LogError("BTLReadoutMapESProducer") + << "BTL electronics mapping not available for BTL crystal layout " << static_cast(btlCrysLayout) + << ", use layout 7 (v4) or later!" << std::endl; + return std::make_unique(); + } + + // -- Initialize mapping helper + BTLElectronicsMapping btlElMapping = BTLElectronicsMapping(); + + auto readoutMap = std::make_unique(); + + // -- Loop over geometry + for (const auto& det : geom.detUnits()) { + BTLDetId modId = BTLDetId(det->geographicalId().rawId()); // this is the sensor module ID + + // -- Select BTL only + if (modId.mtdSubDetector() != MTDDetId::BTL) + continue; + + // -- Loop over crystals in a sensor module + for (uint iCrystal = 0; iCrystal < BTLDetId::kCrystalsPerModuleV2; iCrystal++) { + BTLDetId btlId(modId.mtdSide(), modId.mtdRR(), modId.runit(), modId.dmodule(), modId.smodule(), iCrystal); + + int sl = btlElMapping.slink(btlId); + int hs = btlElMapping.hslink(btlId); + int el = btlElMapping.elink(btlId); + + BTLElectronicsIdPair elecIds; + int ch[2]; + + // -- Loop over two sides of one crystal + for (int side = 0; side < 2; ++side) { + ch[side] = btlElMapping.TOFHIRCh(btlId, side); + + // Safety checks + if (sl < 0 || hs < 0 || (el < 0 || el > 23) || (ch[side] < 0 || ch[side] > 31)) { + throw cms::Exception("BTLReadoutMapESProducer") + << "Invalid electronics mapping for DetId " << btlId.rawId() << " (slink=" << sl << ", hs=" << hs + << ", elink=" << el << ", channel=" << ch << ")"; + } + } + + elecIds.minus = BTLElectronicsId(sl, hs, el, ch[0]); + elecIds.plus = BTLElectronicsId(sl, hs, el, ch[1]); + + readoutMap->add(btlId, elecIds); + } + } + + return readoutMap; +} + +// ------------------------------------------------------------ + +DEFINE_FWK_EVENTSETUP_MODULE(BTLReadoutMapESProducer); diff --git a/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.h b/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.h new file mode 100644 index 0000000000000..6b5a42f8b5aa3 --- /dev/null +++ b/EventFilter/MTDRawToDigi/plugins/BTLReadoutMapESProducer.h @@ -0,0 +1,34 @@ +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "CondFormats/MTDObjects/interface/BTLElectronicsId.h" +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" +#include "CondFormats/DataRecord/interface/BTLReadoutMapRcd.h" + +#include "DataFormats/ForwardDetId/interface/BTLDetId.h" +#include "Geometry/MTDGeometryBuilder/interface/MTDGeometry.h" +#include "Geometry/Records/interface/MTDGeometryRecord.h" +#include "Geometry/Records/interface/MTDDigiGeometryRecord.h" + +#include "Geometry/MTDCommonData/interface/MTDTopologyMode.h" +#include "Geometry/MTDGeometryBuilder/interface/MTDTopology.h" +#include "Geometry/Records/interface/MTDTopologyRcd.h" + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include + +class BTLReadoutMapESProducer : public edm::ESProducer { +public: + BTLReadoutMapESProducer(const edm::ParameterSet&); + ~BTLReadoutMapESProducer() override; + + std::unique_ptr produce(const BTLReadoutMapRcd&); + +private: + edm::ESGetToken geomToken_; + edm::ESGetToken topoToken_; +}; diff --git a/EventFilter/MTDRawToDigi/plugins/BuildFile.xml b/EventFilter/MTDRawToDigi/plugins/BuildFile.xml new file mode 100644 index 0000000000000..90c32fa94b8d5 --- /dev/null +++ b/EventFilter/MTDRawToDigi/plugins/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EventFilter/MTDRawToDigi/src/BTLElectronicsMapping.cc b/EventFilter/MTDRawToDigi/src/BTLElectronicsMapping.cc new file mode 100644 index 0000000000000..74978803944a2 --- /dev/null +++ b/EventFilter/MTDRawToDigi/src/BTLElectronicsMapping.cc @@ -0,0 +1,187 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "EventFilter/MTDRawToDigi/interface/BTLElectronicsSpecs.h" +#include "EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h" +#include + +#include + +BTLElectronicsMapping::BTLElectronicsMapping() {} + +int BTLElectronicsMapping::SiPMCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) const { + if (0 > int(crystal) || crystal > BTLDetId::kCrystalsPerModuleV2) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::SiPMCh " + << "****************** Bad crystal number = " << int(crystal); + return 0; + } + + if (0 > int(smodCopy) || smodCopy > BTLDetId::kSModulesPerDM) { + edm::LogWarning("BTLElectronicsMapping") << "BTLNumberingScheme::getUnitID(): " + << "****************** Bad detector module copy = " << int(smodCopy); + return 0; + } + + if (smodCopy == 0) + return BTLElectronicsSpecs::SiPMChannelMapFW[crystal + SiPMSide * BTLDetId::kCrystalsPerModuleV2]; + else + return BTLElectronicsSpecs::SiPMChannelMapBW[crystal + SiPMSide * BTLDetId::kCrystalsPerModuleV2]; +} + +int BTLElectronicsMapping::SiPMCh(BTLDetId det, uint32_t SiPMSide) const { + uint32_t smodCopy = det.smodule(); + uint32_t crystal = det.crystal(); + return SiPMCh(smodCopy, crystal, SiPMSide); +} + +int BTLElectronicsMapping::SiPMCh(uint32_t rawId, uint32_t SiPMSide) const { + BTLDetId theId(rawId); + return SiPMCh(theId, SiPMSide); +} + +// -- Get TOFHIR Channel Id from crystal Id +int BTLElectronicsMapping::TOFHIRCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) const { + int SiPMCh_ = BTLElectronicsMapping::SiPMCh(smodCopy, crystal, SiPMSide); + return BTLElectronicsSpecs::THChannelMap[SiPMCh_]; +} + +int BTLElectronicsMapping::TOFHIRCh(BTLDetId det, uint32_t SiPMSide) const { + uint32_t smodCopy = det.smodule(); + uint32_t crystal = det.crystal(); + return BTLElectronicsMapping::TOFHIRCh(smodCopy, crystal, SiPMSide); +} + +int BTLElectronicsMapping::TOFHIRCh(uint32_t rawId, uint32_t SiPMSide) const { + BTLDetId theId(rawId); + return BTLElectronicsMapping::TOFHIRCh(theId, SiPMSide); +} + +// -- Get TOFHIR asic number +// if dmodule is odd number (DM range [1-12]) +// SM1 --> TOFHIR A0 (simply 0) +// SM2 --> TOFHIR A1 (simply 1) +// else if dmodule is even number the order is inverted +// SM1 --> TOFHIR A1 (simply 1) +// SM2 --> TOFHIR A0 (simply 0) +int BTLElectronicsMapping::TOFHIRASIC(uint32_t dmodule, uint32_t smodCopy) const { + if (dmodule % BTLDetId::kSModulesInDM == 0) + return smodCopy; + else + return BTLDetId::kSModulesInDM - smodCopy - 1; +} + +int BTLElectronicsMapping::TOFHIRASIC(BTLDetId det) const { + uint32_t dmodule = det.dmodule(); + uint32_t smodCopy = det.smodule(); + return BTLElectronicsMapping::TOFHIRASIC(dmodule, smodCopy); +} + +int BTLElectronicsMapping::TOFHIRASIC(uint32_t rawID) const { + BTLDetId theId(rawID); + return BTLElectronicsMapping::TOFHIRASIC(theId); +} + +// -- Get e-link from a given DM,SM (TOFHIR) +int BTLElectronicsMapping::elinkFromSM(uint32_t dmodule, uint32_t smodCopy, int lpgbt_id) const { + if (int(dmodule) < 0 || dmodule > BTLDetId::kDModulesPerRU) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::elinkFromSM: " + << "****************** dmodule = " << dmodule << " not valid!"; + return -1; + } + + if (int(smodCopy) < 0 || smodCopy > BTLDetId::kSModulesPerDM) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::elinkFromSM: " + << "****************** smodCopy = " << smodCopy << " not valid!"; + return -1; + } + + if (lpgbt_id < 0 || lpgbt_id > 1) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::hslinkFromRU: " + << "****************** lpgbt_id = " << lpgbt_id << " not valid!"; + return -1; + } + + int chipId = TOFHIRASIC(dmodule, smodCopy); + return (lpgbt_id == 0) ? BTLElectronicsSpecs::FE_to_ELINK_mapping_L0[dmodule][chipId] + : BTLElectronicsSpecs::FE_to_ELINK_mapping_L1[dmodule][chipId]; +} + +int BTLElectronicsMapping::elink(BTLDetId det, int lpgbt_id) const { + uint32_t dmodule = det.dmodule(); + uint32_t smodCopy = det.smodule(); + return BTLElectronicsMapping::elinkFromSM(dmodule, smodCopy, lpgbt_id); +} + +int BTLElectronicsMapping::elink(uint32_t rawID, int lpgbt_id) const { + BTLDetId theId(rawID); + return BTLElectronicsMapping::elink(theId, lpgbt_id); +} + +// -- Get HS-link Id from RU and Tray +// TEMPORARY MAPPING: within a group of 6 trays ( = supertray): tray 0 --> first block of 12 links, tray 1--> second block of 12 links, etc. + +int BTLElectronicsMapping::opticalTxPosition(uint32_t tray, int optTxCh) const { + const bool useN5Mapping = (BTLElectronicsSpecs::kHSLinksOffset == 4) && (tray % 6 == 0); + + return useN5Mapping ? BTLElectronicsSpecs::tx_inv_n5[optTxCh] : BTLElectronicsSpecs::tx_inv_common[optTxCh]; +} + +int BTLElectronicsMapping::hslinkFromRU(uint32_t runit, uint32_t tray, int lpgbt_id) const { + if (int(runit) < 0 || runit > BTLDetId::kRUPerRod) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::hslinkFromRU " + << "****************** runit = " << runit << " not valid!"; + return -1; + } + + if (lpgbt_id < 0 || lpgbt_id > 1) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::hslinkFromRU: " + << "****************** lpgbt_id = " << lpgbt_id << " not valid!"; + return -1; + } + + const int optTxCh = 2 * runit + lpgbt_id; + + // pos is the position in the opt tx array + const int pos = opticalTxPosition(tray, optTxCh); + + return (BTLElectronicsSpecs::kHSLinksOffset + 12 * (tray % 6) + pos); +} + +int BTLElectronicsMapping::hslink(BTLDetId det, int lpgbt_id) const { + uint32_t ru = det.runit(); + uint32_t tray = det.mtdRR(); + return BTLElectronicsMapping::hslinkFromRU(ru, tray, lpgbt_id); +} + +int BTLElectronicsMapping::hslink(uint32_t rawID, int lpgbt_id) const { + BTLDetId theId(rawID); + return hslink(theId, lpgbt_id); +} + +int BTLElectronicsMapping::slinkFromTray(uint32_t tray, uint32_t zside) const { + if (int(tray) < 0 || tray >= BTLDetId::HALF_ROD) { + edm::LogWarning("BTLElectronicsMapping") << "BTLElectronicsMapping::SlinkFromTray: " + << "****************** tray = " << tray << " not valid!"; + return -1; + } + + if (int(zside) < 0 || zside > 1) { + edm::LogWarning("BTLElectronicsMapping") + << "BTLElectronicsMapping::SlinkFromTray " + << "****************** zside = " << zside << " not valid (should be 0 or 1)!"; + return -1; + } + // TEMPORARY MAPPING: + // trays [0-35], Z- --> Slinks [0,5] + // trays [0-35], Z+ --> Slinks [6,11] + return (BTLElectronicsSpecs::kFirstFEDId + tray / 6 + 6 * zside); +} + +int BTLElectronicsMapping::slink(BTLDetId det) const { + uint32_t tray = det.mtdRR(); + uint32_t zside = det.mtdSide(); + return BTLElectronicsMapping::slinkFromTray(tray, zside); +} + +int BTLElectronicsMapping::slink(uint32_t rawID) const { + BTLDetId theId(rawID); + return BTLElectronicsMapping::slink(theId); +} diff --git a/EventFilter/MTDRawToDigi/test/BuildFile.xml b/EventFilter/MTDRawToDigi/test/BuildFile.xml new file mode 100644 index 0000000000000..87f5fd159c79f --- /dev/null +++ b/EventFilter/MTDRawToDigi/test/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EventFilter/MTDRawToDigi/test/TestBTLReadoutMap.cc b/EventFilter/MTDRawToDigi/test/TestBTLReadoutMap.cc new file mode 100644 index 0000000000000..ee91e52a3ac78 --- /dev/null +++ b/EventFilter/MTDRawToDigi/test/TestBTLReadoutMap.cc @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ESTransientHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" + +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "Geometry/Records/interface/DDSpecParRegistryRcd.h" + +#include "DetectorDescription/DDCMS/interface/DDDetector.h" +#include "DetectorDescription/DDCMS/interface/DDSolidShapes.h" +#include "DetectorDescription/DDCMS/interface/DDFilteredView.h" +#include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h" + +#include "Geometry/MTDCommonData/interface/MTDBaseNumber.h" +#include "Geometry/MTDCommonData/interface/BTLNumberingScheme.h" +#include "Geometry/MTDCommonData/interface/MTDTopologyMode.h" + +#include "Geometry/MTDGeometryBuilder/interface/MTDTopology.h" +#include "Geometry/Records/interface/MTDTopologyRcd.h" + +#include "DataFormats/ForwardDetId/interface/BTLDetId.h" + +#include "CondFormats/MTDObjects/interface/BTLReadoutMap.h" +#include "CondFormats/DataRecord/interface/BTLReadoutMapRcd.h" +#include "EventFilter/MTDRawToDigi/interface/BTLElectronicsMapping.h" + +#include "DataFormats/Math/interface/angle_units.h" +#include "DataFormats/Math/interface/Rounding.h" +#include + +using namespace cms; + +class TestBTLReadoutMap : public edm::one::EDAnalyzer<> { +public: + explicit TestBTLReadoutMap(const edm::ParameterSet&); + ~TestBTLReadoutMap() override = default; + + void beginJob() override {} + void analyze(edm::Event const&, edm::EventSetup const&) override; + void endJob() override {} + + void theBaseNumber(cms::DDFilteredView& fv); + +private: + const edm::ESInputTag tag_; + std::string ddTopNodeName_; + + MTDBaseNumber thisN_; + BTLNumberingScheme btlNS_; + + edm::ESGetToken mtdtopoToken_; + edm::ESGetToken dddetToken_; + edm::ESGetToken dspecToken_; + edm::ESGetToken readoutMapToken_; +}; + +using DD3Vector = ROOT::Math::DisplacementVector3D>; +using angle_units::operators::convertRadToDeg; +using cms_rounding::roundIfNear0; + +TestBTLReadoutMap::TestBTLReadoutMap(const edm::ParameterSet& iConfig) + : tag_(iConfig.getParameter("DDDetector")), + ddTopNodeName_(iConfig.getUntrackedParameter("ddTopNodeName", "BarrelTimingLayer")), + thisN_(), + btlNS_() { + mtdtopoToken_ = esConsumes(); + dddetToken_ = esConsumes(tag_); + dspecToken_ = esConsumes(tag_); + readoutMapToken_ = esConsumes(); +} + +void TestBTLReadoutMap::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto pDD = iSetup.getTransientHandle(dddetToken_); + + auto pSP = iSetup.getTransientHandle(dspecToken_); + + auto topologyHandle = iSetup.getTransientHandle(mtdtopoToken_); + const MTDTopology* topology = topologyHandle.product(); + auto btlCrysLayout = MTDTopologyMode::crysLayoutFromTopoMode(topology->getMTDTopologyMode()); + + auto const& btlReadoutMap = iSetup.getData(readoutMapToken_); + if (btlReadoutMap.size() == 0) { + edm::LogError("TestBTLReadoutMap") << "BTL readout map is empty !"; + } + + if (ddTopNodeName_ != "BarrelTimingLayer") { + edm::LogWarning("TestBTLReadoutMap") << ddTopNodeName_ << "Not valid top BarrelTimingLayer volume"; + return; + } + + DDFilteredView fv(pDD.product(), pDD.product()->description()->worldVolume()); + fv.next(0); + + DDSpecParRefs specs; + pSP.product()->filter(specs, "ReadOutName", "FastTimerHitsBarrel"); + + bool insideBTL = false; + uint32_t startLevel = 0; + + do { + if (dd4hep::dd::noNamespace(fv.name()) == "BarrelTimingLayer") { + insideBTL = true; + startLevel = fv.navPos().size(); + edm::LogInfo("TestBTLReadoutMap") << "insideBTL = " << insideBTL; + if (static_cast(btlCrysLayout) < static_cast(BTLDetId::CrysLayout::v4)) { + edm::LogInfo("TestBTLReadoutMap") + << "BTL electronics mapping not available for BTL crystal layout " << static_cast(btlCrysLayout) + << ", use layout 7 (v4) or later!" << std::endl; + } + continue; + } + + if (insideBTL && fv.navPos().size() < startLevel) { + break; // exited BTL --> break loop + } + + if (!insideBTL) + continue; + + std::stringstream ss; + + theBaseNumber(fv); + + bool isSens = false; + + for (auto const& t : specs) { + for (auto const& it : t.second->paths) { + if (dd4hep::dd::compareEqual(dd4hep::dd::noNamespace(fv.name()), dd4hep::dd::realTopName(it))) { + isSens = true; + break; + } + } + } + + if (isSens) { + std::stringstream sunitt; + std::stringstream snum; + + BTLDetId theId(btlNS_.getUnitID(thisN_)); + sunitt << theId.rawId(); + snum << theId; + + // --- Compute the crystal ends positions + dd4hep::Box mySens(fv.solid()); + DD3Vector x, y, z; + fv.rotation().GetComponents(x, y, z); + DD3Vector zeroLocal(0., 0., 0.); + DD3Vector plusLocal(mySens.x(), 0., 0.); + DD3Vector plusGlobal = (fv.rotation())(plusLocal) + fv.translation(); + DD3Vector minusLocal(-mySens.x(), 0., 0.); + DD3Vector minusGlobal = (fv.rotation())(minusLocal) + fv.translation(); + + if (static_cast(btlCrysLayout) >= static_cast(BTLDetId::CrysLayout::v4)) { + auto fround = [&](double in) { + std::stringstream ss; + ss << std::fixed << std::setw(14) << roundIfNear0(in); + return ss.str(); + }; + + snum << "\n"; + snum << "- location = " << fround(minusGlobal.X() / dd4hep::mm) << fround(minusGlobal.Y() / dd4hep::mm) + << fround(minusGlobal.Z() / dd4hep::mm) << " r = " << fround(minusGlobal.Rho() / dd4hep::mm) + << " phi = " << fround(convertRadToDeg(minusGlobal.Phi())) << "\n"; + snum << "+ location = " << fround(plusGlobal.X() / dd4hep::mm) << fround(plusGlobal.Y() / dd4hep::mm) + << fround(plusGlobal.Z() / dd4hep::mm) << " r = " << fround(plusGlobal.Rho() / dd4hep::mm) + << " phi = " << fround(convertRadToDeg(plusGlobal.Phi())) << "\n"; + + // --- Check electronics ids + auto const& elecIds = btlReadoutMap.getElectronicsId(theId); + + snum << "\n"; + snum << "BTLElectronicsId (minus) : " << elecIds.minus << "\n" + << "BTLElectronicsId (plus) : " << elecIds.plus << "\n" + << "\n"; + + auto const& detMinus = btlReadoutMap.getDetId(elecIds.minus); + auto const& detPlus = btlReadoutMap.getDetId(elecIds.plus); + + if (detMinus.rawId() != theId.rawId()) { + edm::LogError("TestBTLReadoutMap") << "Reverse mapping mismatch for minus side!"; + } + if (detPlus.rawId() != theId.rawId()) { + edm::LogError("TestBTLReadoutMap") << "Reverse mapping mismatch for plus side!"; + } + + BTLElectronicsMapping btlElMapping = BTLElectronicsMapping(); + snum << " TOFHIRASIC: " << btlElMapping.TOFHIRASIC(theId) + << "\n SiPMCh minus: " << btlElMapping.SiPMCh(theId, 0) << " plus: " << btlElMapping.SiPMCh(theId, 1) + << "\n TOFHIRCh minus: " << btlElMapping.TOFHIRCh(theId, 0) << " plus: " << btlElMapping.TOFHIRCh(theId, 1) + << "\n"; + snum << "\n"; + + snum << "----------------------------------------------------------------------------" << std::endl; + snum << " DM, SM, chipId: " << theId.dmodule() << ", " << theId.smodule() << ", " + << btlElMapping.TOFHIRASIC(theId) << " --> e-link: " << elecIds.minus.eLinkId() << " (" + << elecIds.plus.eLinkId() << ")\n" + << " Side, Tray, RU: " << theId.mtdSide() << ", " << theId.mtdRR() << ", " << theId.runit() + << " --> HS-link : " << elecIds.minus.hsLinkId() << " (" << elecIds.plus.hsLinkId() + << ") FED ID / S-link : " << elecIds.minus.fedId() << " (" << elecIds.plus.fedId() << ")\n" + + << " BTLElectronicsId (minus) rawId : " << elecIds.minus.rawId() + << " --> Side, Tray, RU, DM, SM: " << detMinus.mtdSide() << ", " << detMinus.mtdRR() << ", " + << detMinus.runit() << ", " << detMinus.dmodule() << ", " << detMinus.smodule() << "\n" + + << " BTLElectronicsId (plus) rawId : " << elecIds.plus.rawId() + << " --> Side, Tray, RU, DM, SM: " << detPlus.mtdSide() << ", " << detPlus.mtdRR() << ", " + << detPlus.runit() << ", " << detPlus.dmodule() << ", " << detPlus.smodule() << "\n"; + snum << "----------------------------------------------------------------------------" << std::endl; + } + edm::LogInfo("TestBTLReadoutMap") << snum.str(); + } + } while (fv.next(0)); +} + +void TestBTLReadoutMap::theBaseNumber(cms::DDFilteredView& fv) { + thisN_.reset(); + thisN_.setSize(fv.navPos().size()); + + for (uint ii = 0; ii < fv.navPos().size(); ii++) { + std::string_view name((fv.geoHistory()[ii])->GetName()); + size_t ipos = name.rfind('_'); + thisN_.addLevel(name.substr(0, ipos), fv.copyNos()[ii]); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("TestBTLReadoutMap") << ii << " " << name.substr(0, ipos) << " " << fv.copyNos()[ii]; +#endif + } +} + +DEFINE_FWK_MODULE(TestBTLReadoutMap); diff --git a/EventFilter/MTDRawToDigi/test/testBTLReadoutMap_cfg.py b/EventFilter/MTDRawToDigi/test/testBTLReadoutMap_cfg.py new file mode 100644 index 0000000000000..feb89a59724ca --- /dev/null +++ b/EventFilter/MTDRawToDigi/test/testBTLReadoutMap_cfg.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms + +import Configuration.Geometry.defaultPhase2ConditionsEra_cff as _settings +import Geometry.MTDCommonData.defaultMTDConditionsEra_cff as _mtdgeo +_mtdgeo.check_mtdgeo() +_PH2_GLOBAL_TAG, _PH2_ERA = _settings.get_era_and_conditions(_mtdgeo.MTD_DEFAULT_VERSION) +from Configuration.ProcessModifiers.dd4hep_cff import dd4hep + +process = cms.Process("TEST",_PH2_ERA, dd4hep) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1)) + +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.cerr.threshold = cms.untracked.string('INFO') +process.MessageLogger.cerr.INFO = cms.untracked.PSet( + #limit = cms.untracked.int32(0) + limit = cms.untracked.int32(-1) +) +process.MessageLogger.cerr.TestBTLElectronicsMapping = cms.untracked.PSet( + #limit = cms.untracked.int32(0) + limit = cms.untracked.int32(-1) +) + + +process.load("Geometry.MTDNumberingBuilder.mtdTopology_cfi") +process.load('Geometry.MTDCommonData.GeometryDD4hepExtendedRun4MTDDefaultReco_cff') + +# ESProducer +process.btlReadoutMapESProducer = cms.ESProducer( + "BTLReadoutMapESProducer" +) + +# your test analyzer +process.test = cms.EDAnalyzer("TestBTLReadoutMap", + DDDetector = cms.ESInputTag('',''), + ddTopNodeName = cms.untracked.string('BarrelTimingLayer') +) + +process.p = cms.Path(process.test) diff --git a/Geometry/MTDCommonData/interface/BTLElectronicsMapping.h b/Geometry/MTDCommonData/interface/BTLElectronicsMapping.h deleted file mode 100644 index e0f24781b67d1..0000000000000 --- a/Geometry/MTDCommonData/interface/BTLElectronicsMapping.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef DATAFORMATS_BTLELECTRONICSMAPPING_H -#define DATAFORMATS_BTLELECTRONICSMAPPING_H 1 - -#include -#include - -#include "DataFormats/ForwardDetId/interface/BTLDetId.h" -#include - -/** \brief BTL TOFHIR channel mapping with crystal BTLDetId - Convention: - SiPMside 0 == Minus Side - SiPMside 1 == Plus Side - */ - -class BTLElectronicsMapping { -public: - struct SiPMChPair { - int Minus; - int Plus; - }; - - struct TOFHIRChPair { - int Minus; - int Plus; - }; - - // Map SiPM Channel to crystal bars for Forward module orientation - static constexpr std::array SiPMChannelMapFW{ - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}; - // Map SiPM Channel to crystal bars for Backward module orientation - static constexpr std::array SiPMChannelMapBW{ - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16}}; - - // Map TOFHIR Channel to SiPM Channel - static constexpr std::array THChannelMap{ - {4, 1, 0, 3, 2, 6, 7, 9, 5, 11, 8, 12, 10, 14, 15, 13, - 17, 16, 18, 19, 20, 23, 21, 26, 22, 27, 28, 31, 30, 24, 25, 29}}; - - /** Default constructor -- invalid value */ - BTLElectronicsMapping(const BTLDetId::CrysLayout lay); - - // Get SiPM Channel number from crystal - int SiPMCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide); - int SiPMCh(BTLDetId det, uint32_t SiPMSide); - int SiPMCh(uint32_t rawID, uint32_t SiPMSide); - - SiPMChPair GetSiPMChPair(uint32_t smodCopy, uint32_t crystal); - SiPMChPair GetSiPMChPair(BTLDetId det); - SiPMChPair GetSiPMChPair(uint32_t rawID); - - // Get TOFHIR Channel number from crystal - int TOFHIRCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide); - int TOFHIRCh(BTLDetId det, uint32_t SiPMSide); - int TOFHIRCh(uint32_t rawID, uint32_t SiPMSide); - - TOFHIRChPair GetTOFHIRChPair(uint32_t smodCopy, uint32_t crystal); - TOFHIRChPair GetTOFHIRChPair(BTLDetId det); - TOFHIRChPair GetTOFHIRChPair(uint32_t rawID); - - // Get xtal from TOFHIR Channel number - int THChToXtal(uint32_t smodCopy, uint32_t THCh); - BTLDetId THChToBTLDetId( - uint32_t zside, uint32_t rod, uint32_t runit, uint32_t dmodule, uint32_t smodCopy, uint32_t THCh); - - /** Returns TOFHIR ASIC number in construction database. */ - int TOFHIRASIC(uint32_t dmodule, uint32_t smodCopy); - int TOFHIRASIC(BTLDetId det); - int TOFHIRASIC(uint32_t rawID); - - /** Returns FE board number */ - int FEBoardFromDM(uint32_t dmodule); - int FEBoard(BTLDetId det); - int FEBoard(uint32_t rawID); - - /** Returns CC board number */ - int CCBoardFromRU(uint32_t dmodule); - int CCBoard(BTLDetId det); - int CCBoard(uint32_t rawID); - -private: -}; - -#endif diff --git a/Geometry/MTDCommonData/src/BTLElectronicsMapping.cc b/Geometry/MTDCommonData/src/BTLElectronicsMapping.cc deleted file mode 100644 index 5a487645f1c25..0000000000000 --- a/Geometry/MTDCommonData/src/BTLElectronicsMapping.cc +++ /dev/null @@ -1,218 +0,0 @@ -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "Geometry/MTDCommonData/interface/BTLElectronicsMapping.h" -#include "FWCore/Utilities/interface/Exception.h" -#include - -#include -#include -#include -BTLElectronicsMapping::BTLElectronicsMapping(const BTLDetId::CrysLayout lay) { - if (static_cast(lay) < 7) { - throw cms::Exception("BTLElectronicsMapping") - << "MTD Topology mode with layout " << static_cast(lay) << " is not supported\n" - << "use layout : 7 (v4) or later!" << std::endl; - } -} - -// Get SiPM Channel from crystal ID - -int BTLElectronicsMapping::SiPMCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) { - if (0 > int(crystal) || crystal > BTLDetId::kCrystalsPerModuleV2) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::BTLElectronicsMapping(): " - << "****************** Bad crystal number = " << int(crystal); - return 0; - } - - if (0 > int(smodCopy) || smodCopy > BTLDetId::kSModulesPerDM) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad detector module copy = " << int(smodCopy); - return 0; - } - - if (smodCopy == 0) - return BTLElectronicsMapping::SiPMChannelMapFW[crystal + SiPMSide * BTLDetId::kCrystalsPerModuleV2]; - else - return BTLElectronicsMapping::SiPMChannelMapBW[crystal + SiPMSide * BTLDetId::kCrystalsPerModuleV2]; -} - -int BTLElectronicsMapping::SiPMCh(BTLDetId det, uint32_t SiPMSide) { - uint32_t smodCopy = det.smodule(); - uint32_t crystal = det.crystal(); - - return BTLElectronicsMapping::SiPMCh(smodCopy, crystal, SiPMSide); -} - -int BTLElectronicsMapping::SiPMCh(uint32_t rawId, uint32_t SiPMSide) { - BTLDetId theId(rawId); - return BTLElectronicsMapping::SiPMCh(theId, SiPMSide); -} - -BTLElectronicsMapping::SiPMChPair BTLElectronicsMapping::GetSiPMChPair(uint32_t smodCopy, uint32_t crystal) { - BTLElectronicsMapping::SiPMChPair SiPMChs; - SiPMChs.Minus = BTLElectronicsMapping::SiPMCh(smodCopy, crystal, 0); - SiPMChs.Plus = BTLElectronicsMapping::SiPMCh(smodCopy, crystal, 1); - return SiPMChs; -} - -BTLElectronicsMapping::SiPMChPair BTLElectronicsMapping::GetSiPMChPair(BTLDetId det) { - BTLElectronicsMapping::SiPMChPair SiPMChs; - SiPMChs.Minus = BTLElectronicsMapping::SiPMCh(det, 0); - SiPMChs.Plus = BTLElectronicsMapping::SiPMCh(det, 1); - return SiPMChs; -} -BTLElectronicsMapping::SiPMChPair BTLElectronicsMapping::GetSiPMChPair(uint32_t rawID) { - BTLElectronicsMapping::SiPMChPair SiPMChs; - SiPMChs.Minus = BTLElectronicsMapping::SiPMCh(rawID, 0); - SiPMChs.Plus = BTLElectronicsMapping::SiPMCh(rawID, 1); - return SiPMChs; -} - -// Get TOFHIR Channel from crystal ID - -int BTLElectronicsMapping::TOFHIRCh(uint32_t smodCopy, uint32_t crystal, uint32_t SiPMSide) { - int SiPMCh_ = BTLElectronicsMapping::SiPMCh(smodCopy, crystal, SiPMSide); - return BTLElectronicsMapping::THChannelMap[SiPMCh_]; -} - -int BTLElectronicsMapping::TOFHIRCh(BTLDetId det, uint32_t SiPMSide) { - uint32_t smodCopy = det.smodule(); - uint32_t crystal = det.crystal(); - - return BTLElectronicsMapping::TOFHIRCh(smodCopy, crystal, SiPMSide); -} - -int BTLElectronicsMapping::TOFHIRCh(uint32_t rawId, uint32_t SiPMSide) { - BTLDetId theId(rawId); - return BTLElectronicsMapping::TOFHIRCh(theId, SiPMSide); -} - -BTLElectronicsMapping::TOFHIRChPair BTLElectronicsMapping::GetTOFHIRChPair(uint32_t smodCopy, uint32_t crystal) { - BTLElectronicsMapping::TOFHIRChPair TOFHIRChs; - TOFHIRChs.Minus = BTLElectronicsMapping::TOFHIRCh(smodCopy, crystal, 0); - TOFHIRChs.Plus = BTLElectronicsMapping::TOFHIRCh(smodCopy, crystal, 1); - return TOFHIRChs; -} - -BTLElectronicsMapping::TOFHIRChPair BTLElectronicsMapping::GetTOFHIRChPair(BTLDetId det) { - BTLElectronicsMapping::TOFHIRChPair TOFHIRChs; - TOFHIRChs.Minus = BTLElectronicsMapping::TOFHIRCh(det, 0); - TOFHIRChs.Plus = BTLElectronicsMapping::TOFHIRCh(det, 1); - return TOFHIRChs; -} -BTLElectronicsMapping::TOFHIRChPair BTLElectronicsMapping::GetTOFHIRChPair(uint32_t rawID) { - BTLElectronicsMapping::TOFHIRChPair TOFHIRChs; - TOFHIRChs.Minus = BTLElectronicsMapping::TOFHIRCh(rawID, 0); - TOFHIRChs.Plus = BTLElectronicsMapping::TOFHIRCh(rawID, 1); - return TOFHIRChs; -} - -// Get crystal ID from TOFHIR Channel - -int BTLElectronicsMapping::THChToXtal(uint32_t smodCopy, uint32_t THCh) { - if (0 > int(smodCopy) || BTLDetId::kSModulesPerDM < smodCopy) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad detector module copy = " << int(smodCopy); - return 0; - } - - auto THChPos = - std::find(BTLElectronicsMapping::THChannelMap.begin(), BTLElectronicsMapping::THChannelMap.end(), THCh); - int targetSiPMCh = std::distance(BTLElectronicsMapping::THChannelMap.begin(), THChPos); - - std::array SiPMChMap; - if (smodCopy == 0) - SiPMChMap = BTLElectronicsMapping::SiPMChannelMapFW; - else - SiPMChMap = BTLElectronicsMapping::SiPMChannelMapBW; - - auto targetpos = std::find(SiPMChMap.begin(), SiPMChMap.end(), targetSiPMCh); - return std::distance(SiPMChMap.begin(), targetpos) % BTLDetId::kCrystalsPerModuleV2 + 1; -} - -BTLDetId BTLElectronicsMapping::THChToBTLDetId( - uint32_t zside, uint32_t rod, uint32_t runit, uint32_t dmodule, uint32_t smodCopy, uint32_t THCh) { - if (0 > int(THCh) || 31 < THCh) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad TOFHIR channel = " << int(THCh); - return 0; - } - - if (0 > int(smodCopy) || BTLDetId::kSModulesPerDM < smodCopy) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad detector module copy = " << int(smodCopy); - return 0; - } - - if (0 > int(dmodule) || 12 < dmodule) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad module copy = " << int(dmodule); - return 0; - } - - if (1 > rod || 36 < rod) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad rod copy = " << rod; - return 0; - } - - if (1 < zside) { - edm::LogWarning("MTDGeom") << "BTLNumberingScheme::getUnitID(): " - << "****************** Bad side = " << zside; - return 0; - } - - int crystal = BTLElectronicsMapping::THChToXtal(smodCopy, THCh); - - return BTLDetId(zside, rod, runit, dmodule, smodCopy, crystal); -} - -// Get TOFHIR asic number -// if dmodule is odd number (DM range [1-12]) -// SM1 --> TOFHIR A0 (simply 0) -// SM2 --> TOFHIR A1 (simply 1) -// else if dmodule is even number the order is inverted -// SM1 --> TOFHIR A1 (simply 1) -// SM2 --> TOFHIR A0 (simply 0) -int BTLElectronicsMapping::TOFHIRASIC(uint32_t dmodule, uint32_t smodCopy) { - if (dmodule % BTLDetId::kSModulesInDM == 0) - return smodCopy; - else - return BTLDetId::kSModulesInDM - smodCopy - 1; -} - -int BTLElectronicsMapping::TOFHIRASIC(BTLDetId det) { - uint32_t dmodule = det.dmodule(); - uint32_t smodCopy = det.smodule(); - return BTLElectronicsMapping::TOFHIRASIC(dmodule, smodCopy); -} - -int BTLElectronicsMapping::TOFHIRASIC(uint32_t rawID) { - BTLDetId theId(rawID); - return BTLElectronicsMapping::TOFHIRASIC(theId); -} - -/** Returns FE board number */ -int BTLElectronicsMapping::FEBoardFromDM(uint32_t dmodule) { return dmodule; } - -int BTLElectronicsMapping::FEBoard(BTLDetId det) { - uint32_t dmodule = det.dmodule(); - return BTLElectronicsMapping::FEBoardFromDM(dmodule); -} - -int BTLElectronicsMapping::FEBoard(uint32_t rawID) { - BTLDetId theId(rawID); - return BTLElectronicsMapping::FEBoard(theId); -} - -/** Returns CC board number */ -int BTLElectronicsMapping::CCBoardFromRU(uint32_t runit) { return runit; } - -int BTLElectronicsMapping::CCBoard(BTLDetId det) { - uint32_t runit = det.runit(); - return BTLElectronicsMapping::CCBoardFromRU(runit); -} - -int BTLElectronicsMapping::CCBoard(uint32_t rawID) { - BTLDetId theId(rawID); - return BTLElectronicsMapping::CCBoard(theId); -} diff --git a/Geometry/MTDCommonData/test/DD4hep_TestMTDIdealGeometry.cc b/Geometry/MTDCommonData/test/DD4hep_TestMTDIdealGeometry.cc index 6fd60e327c67d..96061fae29816 100644 --- a/Geometry/MTDCommonData/test/DD4hep_TestMTDIdealGeometry.cc +++ b/Geometry/MTDCommonData/test/DD4hep_TestMTDIdealGeometry.cc @@ -26,7 +26,6 @@ #include "Geometry/MTDCommonData/interface/MTDBaseNumber.h" #include "Geometry/MTDCommonData/interface/BTLNumberingScheme.h" #include "Geometry/MTDCommonData/interface/ETLNumberingScheme.h" -#include "Geometry/MTDCommonData/interface/BTLElectronicsMapping.h" #include "Geometry/MTDCommonData/interface/MTDTopologyMode.h" #include "Geometry/MTDGeometryBuilder/interface/MTDTopology.h" @@ -85,9 +84,8 @@ void DD4hep_TestMTDIdealGeometry::analyze(const edm::Event& iEvent, const edm::E auto pSP = iSetup.getTransientHandle(dspecToken_); - auto topologyHandle = iSetup.getTransientHandle(mtdtopoToken_); - const MTDTopology* topology = topologyHandle.product(); - auto btlCrysLayout = MTDTopologyMode::crysLayoutFromTopoMode(topology->getMTDTopologyMode()); + //auto topologyHandle = iSetup.getTransientHandle(mtdtopoToken_); + //const MTDTopology* topology = topologyHandle.product(); if (ddTopNodeName_ != "BarrelTimingLayer" && ddTopNodeName_ != "EndcapTimingLayer") { edm::LogWarning("DD4hep_TestMTDIdealGeometry") << ddTopNodeName_ << "Not valid top MTD volume"; @@ -153,11 +151,6 @@ void DD4hep_TestMTDIdealGeometry::analyze(const edm::Event& iEvent, const edm::E if (dd4hep::dd::noNamespace(fv.name()) == "BarrelTimingLayer") { isBarrel = true; edm::LogInfo("DD4hep_TestMTDIdealGeometry") << "isBarrel = " << isBarrel; - if (static_cast(btlCrysLayout) < static_cast(BTLDetId::CrysLayout::v4)) { - edm::LogInfo("DD4hep_TestMTDIdealGeometry") - << "BTL electronics mapping not available for BTL crystal layout " << static_cast(btlCrysLayout) - << ", use layout 7 (v4) or later!" << std::endl; - } } else if (dd4hep::dd::noNamespace(fv.name()) == "EndcapTimingLayer") { isBarrel = false; edm::LogInfo("DD4hep_TestMTDIdealGeometry") << "isBarrel = " << isBarrel; @@ -234,17 +227,6 @@ void DD4hep_TestMTDIdealGeometry::analyze(const edm::Event& iEvent, const edm::E BTLDetId theId(btlNS_.getUnitID(thisN_)); sunitt << theId.rawId(); snum << theId; - - if (static_cast(btlCrysLayout) >= static_cast(BTLDetId::CrysLayout::v4)) { - BTLElectronicsMapping btlEM = BTLElectronicsMapping(btlCrysLayout); - snum << "\n"; - snum << "----------------------------------------------------------------------------" << std::endl; - snum << " CCBoard: " << btlEM.CCBoard(theId) << " FEBoard: " << btlEM.FEBoard(theId) - << " TOFHIRASIC: " << btlEM.TOFHIRASIC(theId) << "\n SiPMCh minus: " << btlEM.SiPMCh(theId, 0) - << " plus: " << btlEM.SiPMCh(theId, 1) << "\n TOFHIRCh minus: " << btlEM.TOFHIRCh(theId, 0) - << " plus: " << btlEM.TOFHIRCh(theId, 1) << "\n"; - snum << "----------------------------------------------------------------------------" << std::endl; - } } else { ETLDetId theId(etlNS_.getUnitID(thisN_)); sunitt << theId.rawId();