Back to home page

Project CMSSW displayed by LXR

 
 

    


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    @short plugin parses HGCAL electronics configuration from JSON file
0022  */
0023 class HGCalConfigurationESProducer : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0024 public:
0025   explicit HGCalConfigurationESProducer(const edm::ParameterSet& iConfig)
0026       :  //edm::ESProducer(iConfig),
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     //findingRecord<HGCalModuleConfigurationRcd>();
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     //desc.add<edm::FileInPath>("filename")->setComment("JSON file with FED configuration parameters");
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     // check if json contains key
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     // get value, and override if value_override>=0
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     // get value, and override if value_override>=0
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     // retrieve values from custom JSON format (see HGCalCalibrationESProducer)
0100     edm::FileInPath fedfip(fedjson_);  // e.g. HGCalCommissioning/LocalCalibration/data/config_feds.json
0101     edm::FileInPath modfip(modjson_);  // e.g. HGCalCommissioning/LocalCalibration/data/config_econds.json
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     // consistency check
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     // loop over FEDs in indexer & fill configuration structs: FED > ECON-D > eRx
0119     // follow indexing by HGCalMappingModuleIndexer
0120     // HGCalConfiguration = container class holding FED structs of ECON-D structs of eRx structs
0121     std::unique_ptr<HGCalConfiguration> config_ = std::make_unique<HGCalConfiguration>();
0122     for (std::size_t fedid = 0; fedid < moduleMap.getMaxFEDSize(); ++fedid) {
0123       // sanity checks
0124       if (moduleMap.getFEDReadoutSequences()[fedid].readoutTypes_.empty())  // check if FED exists (non-empty)
0125         continue;                                                           // skip non-existent FED
0126       std::string sfedid = std::to_string(fedid);                           // key in JSON dictionary must be string
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_);  // check required keys are in the JSON, warn otherwise
0131 
0132       // fill FED configurations
0133       HGCalFedConfig fed;
0134       fed.mismatchPassthroughMode = getint(fed_config_data[sfedid]["mismatchPassthroughMode"],
0135                                            bePassthroughMode_);  // ignore ECON-D packet mismatches
0136       fed.cbHeaderMarker = gethex(fed_config_data[sfedid]["cbHeaderMarker"],
0137                                   cbHeaderMarker_);  // begin of event marker/identifier for capture block
0138       fed.slinkHeaderMarker = gethex(fed_config_data[sfedid]["slinkHeaderMarker"],
0139                                      slinkHeaderMarker_);  // begin of event marker/identifier for S-link
0140 
0141       // loop over ECON-D modules in JSON
0142       for (const std::string typecode :
0143            fed_config_data[sfedid]["econds"]) {  // loop over module typecodes in JSON file (e.g. "ML-F3PT-TX-0003")
0144 
0145         // sanity checks for ECON-Ds
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_);  // check required keys are in the JSON, warn otherwise
0154         if (imod >= fed.econds.size())
0155           fed.econds.resize(imod + 1);
0156 
0157         // fill ECON-D configuration
0158         HGCalECONDConfig mod;
0159         mod.headerMarker = gethex(mod_config_data[typecode]["headerMarker"],
0160                                   econdHeaderMarker_);  // begin of event marker/identifier for capture block
0161         mod.passThrough = getint(mod_config_data[typecode]["passthrough"], econPassthroughMode_);
0162 
0163         // sanity checks for eRx half-ROCs
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         // fill eRX (half-ROC) configuration
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           //roc.charMode = getint(mod_config_data[typecode]["characMode"],charMode_);
0179           roc.charMode = getint(mod_config_data[typecode]["CalibrationSC"][iroc], charMode_);
0180           mod.rocs[iroc] = roc;  // add to ECON-D's vector<HGCalROCConfig> of eRx half-ROCs
0181         }
0182         fed.econds[imod] = mod;  // add to FED's vector<HGCalECONDConfig> of ECON-D modules
0183       }
0184 
0185       config_->feds.push_back(fed);  // add to config's vector of HGCalFedConfig FEDs
0186     }
0187 
0188     // consistency check
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   }  // end of produce()
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_;         // JSON file
0210   const std::string modjson_;         // JSON file
0211   int32_t bePassthroughMode_ = -1;    // for manual override
0212   int32_t cbHeaderMarker_ = -1;       // for manual override
0213   int32_t slinkHeaderMarker_ = -1;    // for manual override
0214   int32_t econdHeaderMarker_ = -1;    // for manual override
0215   int32_t econPassthroughMode_ = -1;  // for manual override
0216   int32_t charMode_ = -1;             // for manual override
0217   int32_t gain_ = -1;                 // for manual override
0218 };
0219 
0220 DEFINE_FWK_EVENTSETUP_SOURCE(HGCalConfigurationESProducer);