File indexing completed on 2025-01-18 03:42:14
0001 #include "FWCore/Framework/interface/MakerMacros.h"
0002 #include "FWCore/Framework/interface/SourceFactory.h"
0003 #include "FWCore/Framework/interface/ESHandle.h"
0004 #include "FWCore/Framework/interface/ESProducer.h"
0005 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0006 #include "FWCore/Framework/interface/ESProducts.h"
0007 #include "FWCore/Utilities/interface/ESGetToken.h"
0008 #include "FWCore/Utilities/interface/do_nothing_deleter.h"
0009 #include "FWCore/ParameterSet/interface/FileInPath.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h"
0012 #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h"
0013 #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h"
0014 #include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" // depends on HGCalElectronicsMappingRcd
0015 #include <string> // for std::to_string
0016 #include <fstream> // needed to read json file with std::ifstream
0017 #include <nlohmann/json.hpp>
0018 using json = nlohmann::json;
0019
0020
0021
0022
0023 class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0024 public:
0025 explicit HGCalConfigurationESProducer(const edm::ParameterSet& iConfig)
0026 :
0027 fedjson_(iConfig.getParameter<std::string>("fedjson")),
0028 modjson_(iConfig.getParameter<std::string>("modjson")) {
0029 if (iConfig.exists("bePassthroughMode"))
0030 bePassthroughMode_ = iConfig.getParameter<int32_t>("bePassthroughMode");
0031 if (iConfig.exists("econPassthroughMode"))
0032 econPassthroughMode_ = iConfig.getParameter<int32_t>("econPassthroughMode");
0033 if (iConfig.exists("cbHeaderMarker"))
0034 cbHeaderMarker_ = iConfig.getParameter<int32_t>("cbHeaderMarker");
0035 if (iConfig.exists("slinkHeaderMarker"))
0036 slinkHeaderMarker_ = iConfig.getParameter<int32_t>("slinkHeaderMarker");
0037 if (iConfig.exists("econdHeaderMarker"))
0038 econdHeaderMarker_ = iConfig.getParameter<int32_t>("econdHeaderMarker");
0039 if (iConfig.exists("charMode"))
0040 charMode_ = iConfig.getParameter<int32_t>("charMode");
0041 if (iConfig.exists("gain"))
0042 gain_ = iConfig.getParameter<int32_t>("gain");
0043 auto cc = setWhatProduced(this);
0044
0045 indexToken_ = cc.consumes(iConfig.getParameter<edm::ESInputTag>("indexSource"));
0046 }
0047
0048 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0049 edm::ParameterSetDescription desc;
0050 desc.add<edm::ESInputTag>("indexSource", edm::ESInputTag(""))
0051 ->setComment("Label for module indexer to set SoA size");
0052
0053 desc.add<std::string>("fedjson", "")->setComment("JSON file with FED configuration parameters");
0054 desc.add<std::string>("modjson", "")->setComment("JSON file with ECOND configuration parameters");
0055 desc.addOptional<int32_t>("bePassthroughMode", -1)
0056 ->setComment("Manual override for mismatch passthrough mode in the BE");
0057 desc.addOptional<int32_t>("econPassthroughMode", -1)->setComment("Manual override passthrough mode in the ECON-D");
0058 desc.addOptional<int32_t>("cbHeaderMarker", -1)
0059 ->setComment("Manual override for capture block header marker (BEO, e.g 0x7f)");
0060 desc.addOptional<int32_t>("slinkHeaderMarker", -1)
0061 ->setComment("Manual override for S-link header marker (BEO, e.g 0x55)");
0062 desc.addOptional<int32_t>("econdHeaderMarker", -1)
0063 ->setComment("Manual override for ECON-D header marker (BEO, e.g 0x154)");
0064 desc.addOptional<int32_t>("charMode", -1)->setComment("Manual override for ROC characterization mode");
0065 desc.addOptional<int32_t>("gain", -1)->setComment("Manual override for ROC gain");
0066 descriptions.addWithDefaultLabel(desc);
0067 }
0068
0069 static bool checkkeys(const json& data,
0070 const std::string& firstkey,
0071 const std::vector<std::string>& keys,
0072 const std::string& fname) {
0073
0074 bool iscomplete = true;
0075 for (auto const& key : keys) {
0076 if (not data[firstkey].contains(key)) {
0077 edm::LogWarning("HGCalConfigurationESProducer::checkkeys")
0078 << " JSON is missing key '" << key << "' for " << firstkey << "!"
0079 << " Please check file " << fname;
0080 iscomplete = false;
0081 }
0082 }
0083 return iscomplete;
0084 }
0085
0086 static int32_t gethex(const std::string& value, const int32_t value_override) {
0087
0088 return (value_override >= 0 ? value_override : std::stoi(value, nullptr, 16));
0089 }
0090
0091 static int32_t getint(const int32_t value, const int32_t value_override) {
0092
0093 return (value_override >= 0 ? value_override : value);
0094 }
0095
0096 std::unique_ptr<HGCalConfiguration> produce(const HGCalModuleConfigurationRcd& iRecord) {
0097 auto const& moduleMap = iRecord.get(indexToken_);
0098
0099
0100 edm::FileInPath fedfip(fedjson_);
0101 edm::FileInPath modfip(modjson_);
0102 std::ifstream fedfile(fedfip.fullPath());
0103 std::ifstream modfile(modfip.fullPath());
0104 const json fed_config_data = json::parse(fedfile);
0105 const json mod_config_data = json::parse(modfile);
0106
0107
0108 uint32_t nfeds = moduleMap.getNFED();
0109 uint32_t ntot_mods = 0, ntot_rocs = 0;
0110 const std::vector<std::string> fedkeys = {
0111 "mismatchPassthroughMode", "cbHeaderMarker", "slinkHeaderMarker", "econds"};
0112 const std::vector<std::string> modkeys = {"headerMarker", "passthrough", "Gain", "CalibrationSC"};
0113 if (nfeds != fed_config_data.size())
0114 edm::LogWarning("HGCalConfigurationESProducer")
0115 << "Total number of FEDs found in JSON file " << fedjson_ << " (" << fed_config_data.size()
0116 << ") does not match indexer (" << nfeds << ")";
0117
0118
0119
0120
0121 std::unique_ptr<HGCalConfiguration> config_ = std::make_unique<HGCalConfiguration>();
0122 for (std::size_t fedid = 0; fedid < moduleMap.getMaxFEDSize(); ++fedid) {
0123
0124 if (moduleMap.getFEDReadoutSequences()[fedid].readoutTypes_.empty())
0125 continue;
0126 std::string sfedid = std::to_string(fedid);
0127 if (!fed_config_data.contains(sfedid))
0128 edm::LogWarning("HGCalConfigurationESProducer")
0129 << " Did not find FED index " << sfedid << " in JSON file " << fedjson_ << "...";
0130 checkkeys(fed_config_data, sfedid, fedkeys, fedjson_);
0131
0132
0133 HGCalFedConfig fed;
0134 fed.mismatchPassthroughMode = getint(fed_config_data[sfedid]["mismatchPassthroughMode"],
0135 bePassthroughMode_);
0136 fed.cbHeaderMarker = gethex(fed_config_data[sfedid]["cbHeaderMarker"],
0137 cbHeaderMarker_);
0138 fed.slinkHeaderMarker = gethex(fed_config_data[sfedid]["slinkHeaderMarker"],
0139 slinkHeaderMarker_);
0140
0141
0142 for (const std::string typecode :
0143 fed_config_data[sfedid]["econds"]) {
0144
0145
0146 ntot_mods++;
0147 const auto& [fedid2, imod] = moduleMap.getIndexForFedAndModule(typecode);
0148 if (fedid != fedid2)
0149 edm::LogWarning("HGCalConfigurationESProducer")
0150 << " FED index from HGCalMappingModuleIndexer (" << fedid << ") does not match that of the JSON file ("
0151 << fedid2 << ", " << fedjson_ << ") for ECON-D module with typecode " << typecode << " and id=" << imod
0152 << "!";
0153 checkkeys(mod_config_data, typecode, modkeys, modjson_);
0154 if (imod >= fed.econds.size())
0155 fed.econds.resize(imod + 1);
0156
0157
0158 HGCalECONDConfig mod;
0159 mod.headerMarker = gethex(mod_config_data[typecode]["headerMarker"],
0160 econdHeaderMarker_);
0161 mod.passThrough = getint(mod_config_data[typecode]["passthrough"], econPassthroughMode_);
0162
0163
0164 uint32_t nrocs = moduleMap.getMaxERxSize(fedid, imod);
0165 uint32_t nrocs2 = mod_config_data[typecode]["Gain"].size();
0166 if (nrocs != nrocs2)
0167 edm::LogWarning("HGCalConfigurationESProducer")
0168 << " Number of eRx ROCs for ECON-D " << typecode << " in " << fedjson_ << " (" << nrocs2
0169 << ") does not match that of the indexer for fedid" << fedid << " & imod=" << imod << " (" << nrocs
0170 << ")!";
0171 mod.rocs.resize(nrocs);
0172
0173
0174 for (uint32_t iroc = 0; iroc < nrocs; iroc++) {
0175 ntot_rocs++;
0176 HGCalROCConfig roc;
0177 roc.gain = (uint8_t)mod_config_data[typecode]["Gain"][iroc];
0178
0179 roc.charMode = getint(mod_config_data[typecode]["CalibrationSC"][iroc], charMode_);
0180 mod.rocs[iroc] = roc;
0181 }
0182 fed.econds[imod] = mod;
0183 }
0184
0185 config_->feds.push_back(fed);
0186 }
0187
0188
0189 if (ntot_mods != moduleMap.getMaxModuleSize())
0190 edm::LogWarning("HGCalConfigurationESProducer")
0191 << "Total number of ECON-D modules found in JSON file " << modjson_ << " (" << ntot_mods
0192 << ") does not match indexer (" << moduleMap.getMaxModuleSize() << ")";
0193 if (ntot_rocs != moduleMap.getMaxERxSize())
0194 edm::LogWarning("HGCalConfigurationESProducer")
0195 << "Total number of eRx half-ROCs found in JSON file " << modjson_ << " (" << ntot_rocs
0196 << ") does not match indexer (" << moduleMap.getMaxERxSize() << ")";
0197
0198 return config_;
0199 }
0200
0201 private:
0202 void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0203 const edm::IOVSyncValue&,
0204 edm::ValidityInterval& oValidity) override {
0205 oValidity = edm::ValidityInterval(edm::IOVSyncValue::beginOfTime(), edm::IOVSyncValue::endOfTime());
0206 }
0207
0208 edm::ESGetToken<HGCalMappingModuleIndexer, HGCalElectronicsMappingRcd> indexToken_;
0209 const std::string fedjson_;
0210 const std::string modjson_;
0211 int32_t bePassthroughMode_ = -1;
0212 int32_t cbHeaderMarker_ = -1;
0213 int32_t slinkHeaderMarker_ = -1;
0214 int32_t econdHeaderMarker_ = -1;
0215 int32_t econPassthroughMode_ = -1;
0216 int32_t charMode_ = -1;
0217 int32_t gain_ = -1;
0218 };
0219
0220 DEFINE_FWK_EVENTSETUP_SOURCE(HGCalConfigurationESProducer);