Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-05-27 01:56:30

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/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/ParameterSet/interface/FileInPath.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 
0013 #include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h"
0014 #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h"
0015 #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h"
0016 #include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h"  // depends on HGCalElectronicsMappingRcd
0017 #include "RecoLocalCalo/HGCalRecAlgos/interface/HGCalESProducerTools.h"    // for json, search_modkey, search_fedkey
0018 
0019 #include <string>   // for std::to_string
0020 #include <fstream>  // needed to read json file with std::ifstream
0021 
0022 /**
0023  * @short ESProducer to parse HGCAL electronics configuration from JSON file
0024  */
0025 class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0026 public:
0027   explicit HGCalConfigurationESProducer(const edm::ParameterSet& iConfig)
0028       :  //edm::ESProducer(iConfig),
0029         fedjson_(iConfig.getParameter<std::string>("fedjson")),
0030         modjson_(iConfig.getParameter<std::string>("modjson")) {
0031     if (iConfig.exists("bePassthroughMode"))
0032       bePassthroughMode_ = iConfig.getParameter<int32_t>("bePassthroughMode");
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     auto cc = setWhatProduced(this);
0042     indexToken_ = cc.consumes(iConfig.getParameter<edm::ESInputTag>("indexSource"));
0043   }
0044 
0045   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0046     edm::ParameterSetDescription desc;
0047     desc.add<edm::ESInputTag>("indexSource", edm::ESInputTag(""))
0048         ->setComment("Label for module indexer to set SoA size");
0049     desc.add<std::string>("fedjson", "")->setComment("JSON file with FED configuration parameters");
0050     desc.add<std::string>("modjson", "")->setComment("JSON file with ECOND configuration parameters");
0051     desc.addOptional<int32_t>("bePassthroughMode", -1)
0052         ->setComment("Manual override for mismatch passthrough mode in the BE");
0053     desc.addOptional<int32_t>("cbHeaderMarker", -1)
0054         ->setComment("Manual override for capture block header marker (BEO, e.g 0x7f)");
0055     desc.addOptional<int32_t>("slinkHeaderMarker", -1)
0056         ->setComment("Manual override for S-link header marker (BEO, e.g 0x55)");
0057     desc.addOptional<int32_t>("econdHeaderMarker", -1)
0058         ->setComment("Manual override for ECON-D header marker (BEO, e.g 0x154)");
0059     desc.addOptional<int32_t>("charMode", -1)->setComment("Manual override for ROC characterization mode");
0060     descriptions.addWithDefaultLabel(desc);
0061   }
0062 
0063   // @short get hexadecimal value, and override if value_override>=0
0064   static int32_t gethex(const std::string& value, const int32_t value_override) {
0065     return (value_override >= 0 ? value_override : std::stoi(value, nullptr, 16));
0066   }
0067 
0068   // @short get integer value, and override if value_override>=0
0069   static int32_t getint(const int32_t value, const int32_t value_override) {
0070     return (value_override >= 0 ? value_override : value);
0071   }
0072 
0073   std::unique_ptr<HGCalConfiguration> produce(const HGCalModuleConfigurationRcd& iRecord) {
0074     auto const& moduleMap = iRecord.get(indexToken_);
0075     edm::LogInfo("HGCalConfigurationESProducer")
0076         << "produce: fedjson_=" << fedjson_ << ",\n         modjson_=" << modjson_;
0077 
0078     // retrieve values from custom JSON format (see HGCalCalibrationESProducer)
0079     edm::FileInPath fedfip(fedjson_);  // e.g. HGCalCommissioning/LocalCalibration/data/config_feds.json
0080     edm::FileInPath modfip(modjson_);  // e.g. HGCalCommissioning/LocalCalibration/data/config_econds.json
0081     std::ifstream fedfile(fedjson_);
0082     std::ifstream modfile(modjson_);
0083     const json fed_config_data = json::parse(fedfile, nullptr, true, /*ignore_comments*/ true);
0084     const json mod_config_data = json::parse(modfile, nullptr, true, /*ignore_comments*/ true);
0085 
0086     // consistency check
0087     uint32_t nfeds = moduleMap.getNumFEDs();
0088     uint32_t ntot_mods = 0, ntot_rocs = 0;
0089     const std::vector<std::string> fedkeys = {"mismatchPassthroughMode", "cbHeaderMarker", "slinkHeaderMarker"};
0090     const std::vector<std::string> modkeys = {"headerMarker", "CalibrationSC"};
0091     if (nfeds != fed_config_data.size())
0092       edm::LogWarning("HGCalConfigurationESProducer")
0093           << "Total number of FEDs found in JSON file " << fedjson_ << " (" << fed_config_data.size()
0094           << ") does not match indexer (" << nfeds << ")";
0095 
0096     // loop over FEDs in indexer & fill configuration structs: FED > ECON-D > eRx
0097     // follow indexing by HGCalMappingModuleIndexer
0098     // HGCalConfiguration = container class holding FED structs of ECON-D structs of eRx structs
0099     std::unique_ptr<HGCalConfiguration> config_ = std::make_unique<HGCalConfiguration>();
0100     for (std::size_t fedid = 0; fedid < moduleMap.getMaxFEDSize(); ++fedid) {
0101       // sanity checks
0102       if (moduleMap.getFEDReadoutSequences()[fedid].readoutTypes_.empty())         // check if FED exists (non-empty)
0103         continue;                                                                  // skip non-existent FED
0104       const auto fedkey = hgcal::search_fedkey(fedid, fed_config_data, fedjson_);  // search matching key
0105       hgcal::check_keys(
0106           fed_config_data, fedkey, fedkeys, fedjson_);  // check required keys are in the JSON, warn otherwise
0107 
0108       // fill FED configurations
0109       HGCalFedConfig fed;
0110       fed.mismatchPassthroughMode = getint(fed_config_data[fedkey]["mismatchPassthroughMode"],
0111                                            bePassthroughMode_);  // ignore ECON-D packet mismatches
0112       fed.cbHeaderMarker = gethex(fed_config_data[fedkey]["cbHeaderMarker"],
0113                                   cbHeaderMarker_);  // begin of event marker/identifier for capture block
0114       fed.slinkHeaderMarker = gethex(fed_config_data[fedkey]["slinkHeaderMarker"],
0115                                      slinkHeaderMarker_);  // begin of event marker/identifier for S-link
0116 
0117       // loop over module typecodes (e.g. "ML-F3PT-TX-0003")
0118       for (const auto& [typecode, ids] : moduleMap.getTypecodeMap()) {
0119         auto [fedid_, imod] = ids;
0120         if (fedid_ != fedid)
0121           continue;
0122 
0123         // sanity checks for ECON-Ds
0124         ntot_mods++;
0125         const auto modkey = hgcal::search_modkey(typecode, mod_config_data, modjson_);  // search matching key
0126         hgcal::check_keys(
0127             mod_config_data, modkey, modkeys, modjson_);  // check required keys are in the JSON, warn otherwise
0128         if (imod >= fed.econds.size())
0129           fed.econds.resize(imod + 1);
0130 
0131         // fill ECON-D configuration
0132         // headerMarker: begin of event marker/identifier for capture block
0133         HGCalECONDConfig mod;
0134         mod.headerMarker = gethex(mod_config_data[modkey]["headerMarker"], econdHeaderMarker_);
0135 
0136         // sanity checks for eRx half-ROCs
0137         uint32_t nrocs = moduleMap.getNumERxs(fedid, imod);
0138         uint32_t nrocs2 = mod_config_data[modkey]["CalibrationSC"].size();
0139         if (nrocs != nrocs2)
0140           edm::LogWarning("HGCalConfigurationESProducer")
0141               << " Number of eRx ROCs for ECON-D " << typecode << " in " << fedjson_ << " (" << nrocs2
0142               << ") does not match that of the indexer for fedid" << fedid << " & imod=" << imod << " (" << nrocs
0143               << ")!";
0144         mod.rocs.resize(nrocs);
0145 
0146         // fill eRX (half-ROC) configuration
0147         for (uint32_t iroc = 0; iroc < nrocs; iroc++) {
0148           ntot_rocs++;
0149           HGCalROCConfig roc;
0150           roc.charMode = getint(mod_config_data[modkey]["CalibrationSC"][iroc], charMode_);
0151           mod.rocs[iroc] = roc;  // add to ECON-D's vector<HGCalROCConfig> of eRx half-ROCs
0152         }
0153         fed.econds[imod] = mod;  // add to FED's vector<HGCalECONDConfig> of ECON-D modules
0154       }
0155 
0156       config_->feds.push_back(fed);  // add to config's vector of HGCalFedConfig FEDs
0157     }
0158 
0159     // consistency check
0160     if (ntot_mods != moduleMap.getMaxModuleSize())
0161       edm::LogWarning("HGCalConfigurationESProducer")
0162           << "Total number of ECON-D modules found in JSON file " << modjson_ << " (" << ntot_mods
0163           << ") does not match indexer (" << moduleMap.getMaxModuleSize() << ")";
0164     if (ntot_rocs != moduleMap.getMaxERxSize())
0165       edm::LogWarning("HGCalConfigurationESProducer")
0166           << "Total number of eRx half-ROCs found in JSON file " << modjson_ << " (" << ntot_rocs
0167           << ") does not match indexer (" << moduleMap.getMaxERxSize() << ")";
0168 
0169     return config_;
0170   }  // end of produce()
0171 
0172 private:
0173   void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0174                       const edm::IOVSyncValue&,
0175                       edm::ValidityInterval& oValidity) override {
0176     oValidity = edm::ValidityInterval(edm::IOVSyncValue::beginOfTime(), edm::IOVSyncValue::endOfTime());
0177   }
0178 
0179   edm::ESGetToken<HGCalMappingModuleIndexer, HGCalElectronicsMappingRcd> indexToken_;
0180   const std::string fedjson_;       // JSON file
0181   const std::string modjson_;       // JSON file
0182   int32_t bePassthroughMode_ = -1;  // for manual override
0183   int32_t cbHeaderMarker_ = -1;     // for manual override
0184   int32_t slinkHeaderMarker_ = -1;  // for manual override
0185   int32_t econdHeaderMarker_ = -1;  // for manual override
0186   int32_t charMode_ = -1;           // for manual override
0187 };
0188 
0189 DEFINE_FWK_EVENTSETUP_SOURCE(HGCalConfigurationESProducer);