File indexing completed on 2023-03-17 10:42:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "FWCore/Framework/interface/SourceFactory.h"
0017 #include "FWCore/Framework/interface/ESHandle.h"
0018 #include "FWCore/Framework/interface/ESProducer.h"
0019 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0020 #include "FWCore/Framework/interface/ESProducts.h"
0021
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023
0024 #include "CondFormats/PPSObjects/interface/PPSTimingCalibration.h"
0025 #include "CondFormats/DataRecord/interface/PPSTimingCalibrationRcd.h"
0026
0027 #include <boost/property_tree/json_parser.hpp>
0028 #include <boost/property_tree/ptree.hpp>
0029
0030 namespace pt = boost::property_tree;
0031
0032
0033
0034 class PPSTimingCalibrationESSource : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0035 public:
0036 PPSTimingCalibrationESSource(const edm::ParameterSet&);
0037
0038 edm::ESProducts<std::unique_ptr<PPSTimingCalibration> > produce(const PPSTimingCalibrationRcd&);
0039
0040 static void fillDescriptions(edm::ConfigurationDescriptions&);
0041
0042 private:
0043 enum struct DetectorType { INVALID = 0, TOTEM_UFSD = 1, PPS_DIAMOND = 2 };
0044
0045 void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0046 const edm::IOVSyncValue&,
0047 edm::ValidityInterval&) override;
0048
0049
0050 std::unique_ptr<PPSTimingCalibration> parseTotemUFSDJsonFile() const;
0051
0052 std::unique_ptr<PPSTimingCalibration> parsePPSDiamondJsonFile() const;
0053
0054 const std::string filename_;
0055 DetectorType subdetector_;
0056 };
0057
0058
0059
0060 PPSTimingCalibrationESSource::PPSTimingCalibrationESSource(const edm::ParameterSet& iConfig)
0061 : filename_(iConfig.getParameter<edm::FileInPath>("calibrationFile").fullPath()),
0062 subdetector_((DetectorType)iConfig.getParameter<unsigned int>("subDetector")) {
0063 setWhatProduced(this);
0064 findingRecord<PPSTimingCalibrationRcd>();
0065 }
0066
0067
0068
0069 edm::ESProducts<std::unique_ptr<PPSTimingCalibration> > PPSTimingCalibrationESSource::produce(
0070 const PPSTimingCalibrationRcd&) {
0071 switch (subdetector_) {
0072 case DetectorType::TOTEM_UFSD:
0073 return edm::es::products(parseTotemUFSDJsonFile());
0074 case DetectorType::PPS_DIAMOND:
0075 return edm::es::products(parsePPSDiamondJsonFile());
0076 default:
0077 throw cms::Exception("PPSTimingCalibrationESSource") << "Subdetector " << (int)subdetector_ << " not recognised!";
0078 }
0079 }
0080
0081
0082
0083 void PPSTimingCalibrationESSource::setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0084 const edm::IOVSyncValue&,
0085 edm::ValidityInterval& oValidity) {
0086 oValidity = edm::ValidityInterval(edm::IOVSyncValue::beginOfTime(), edm::IOVSyncValue::endOfTime());
0087 }
0088
0089
0090
0091 std::unique_ptr<PPSTimingCalibration> PPSTimingCalibrationESSource::parseTotemUFSDJsonFile() const {
0092 pt::ptree mother_node;
0093 pt::read_json(filename_, mother_node);
0094
0095 const std::string formula = mother_node.get<std::string>("formula");
0096 PPSTimingCalibration::ParametersMap params;
0097 PPSTimingCalibration::TimingMap time_info;
0098
0099 for (pt::ptree::value_type& par : mother_node.get_child("parameters")) {
0100 PPSTimingCalibration::Key key;
0101 key.db = (int)strtol(par.first.data(), nullptr, 10);
0102
0103 for (pt::ptree::value_type& board : par.second) {
0104 key.sampic = board.second.get<int>("sampic");
0105 key.channel = board.second.get<int>("channel");
0106 double timeOffset = board.second.get<double>("time_offset");
0107 double timePrecision = board.second.get<double>("time_precision");
0108 key.cell = -1;
0109 time_info[key] = {timeOffset, timePrecision};
0110
0111 int cell_ct = 0;
0112 for (pt::ptree::value_type& cell : board.second.get_child("cells")) {
0113 std::vector<double> values;
0114 key.cell = cell_ct;
0115
0116 for (pt::ptree::value_type& param : cell.second)
0117 values.emplace_back(std::stod(param.second.data(), nullptr));
0118 params[key] = values;
0119 cell_ct++;
0120 }
0121 }
0122 }
0123 return std::make_unique<PPSTimingCalibration>(formula, params, time_info);
0124 }
0125
0126 std::unique_ptr<PPSTimingCalibration> PPSTimingCalibrationESSource::parsePPSDiamondJsonFile() const {
0127 pt::ptree mother_node;
0128 pt::read_json(filename_, mother_node);
0129
0130 const std::string formula = mother_node.get<std::string>("formula");
0131 PPSTimingCalibration::ParametersMap params;
0132 PPSTimingCalibration::TimingMap time_info;
0133
0134 for (pt::ptree::value_type& par : mother_node.get_child("Parameters.Sectors")) {
0135 PPSTimingCalibration::Key key;
0136 key.db = par.second.get<int>("sector");
0137
0138 for (pt::ptree::value_type& st : par.second.get_child("Stations")) {
0139 key.sampic = st.second.get<int>("station");
0140
0141 for (pt::ptree::value_type& pl : st.second.get_child("Planes")) {
0142 key.channel = pl.second.get<int>("plane");
0143
0144 for (pt::ptree::value_type& ch : pl.second.get_child("Channels")) {
0145 key.cell = ch.second.get<int>("channel");
0146 double timeOffset = ch.second.get<double>("time_offset");
0147 double timePrecision = ch.second.get<double>("time_precision");
0148 time_info[key] = {timeOffset, timePrecision};
0149
0150 std::vector<double> values;
0151 for (pt::ptree::value_type& param : ch.second.get_child("param"))
0152 values.emplace_back(std::stod(param.second.data(), nullptr));
0153 params[key] = values;
0154 }
0155 }
0156 }
0157 }
0158 return std::make_unique<PPSTimingCalibration>(formula, params, time_info);
0159 }
0160
0161 void PPSTimingCalibrationESSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0162 edm::ParameterSetDescription desc;
0163 desc.add<edm::FileInPath>("calibrationFile", edm::FileInPath())
0164 ->setComment("file with SAMPIC calibrations, ADC and INL; if empty or corrupted, no calibration will be applied");
0165 desc.add<unsigned int>("subDetector", (unsigned int)PPSTimingCalibrationESSource::DetectorType::INVALID)
0166 ->setComment("type of sub-detector for which the calibrations are provided");
0167
0168 descriptions.add("ppsTimingCalibrationESSource", desc);
0169 }
0170
0171 DEFINE_FWK_EVENTSETUP_SOURCE(PPSTimingCalibrationESSource);