CMS 3D CMS Logo

PPSDiamondSampicTimingCalibrationPCLHarvester.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: CalibPPS/TimingCalibration/PPSDiamondSampicTimingCalibrationPCLHarvester
4 // Class: PPSDiamondSampicTimingCalibrationPCLHarvester
5 //
13 //
14 // Original Author: Christopher Misan
15 // Created: Mon, 26 Jul 2021 16:36:13 GMT
16 //
17 //
18 #include "TAxis.h"
19 #include "TH1.h"
20 #include "TArrayD.h"
22 
29 
30 #include <boost/property_tree/json_parser.hpp>
31 #include <boost/property_tree/ptree.hpp>
32 
35 
38 
42 
43 namespace pt = boost::property_tree;
44 
46 public:
48  void beginRun(const edm::Run&, const edm::EventSetup&) override;
50 
51 private:
53  void calibJson(DQMStore::IGetter& iGetter);
54  void calibDb(DQMStore::IGetter& iGetter);
55  bool getDbSampicChannel(
56  DQMStore::IGetter& iGetter, int& db, int& sampic, int& channel, std::string ch_name, CTPPSDiamondDetId detid);
60  std::vector<CTPPSDiamondDetId> detids_;
62  const unsigned int min_entries_;
64 };
65 
66 //------------------------------------------------------------------------------
67 
69  const edm::ParameterSet& iConfig)
70  : geomEsToken_(esConsumes<edm::Transition::BeginRun>()),
71  dqmDir_(iConfig.getParameter<std::string>("dqmDir")),
72  min_entries_(iConfig.getParameter<unsigned int>("minEntries")),
73  jsonCalibFile_(iConfig.getParameter<std::string>("jsonCalibFile")),
74  jsonOutputPath_(iConfig.getParameter<std::string>("jsonOutputPath")) {
75  if (jsonCalibFile_.empty())
76  timingCalibrationToken_ = esConsumes<edm::Transition::BeginRun>(
77  edm::ESInputTag(iConfig.getParameter<std::string>("timingCalibrationTag")));
78 }
79 
80 //------------------------------------------------------------------------------
81 
83  if (jsonCalibFile_.empty())
85  const auto& geom = iSetup.getData(geomEsToken_);
86  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
87  if (!CTPPSDiamondDetId::check(it->first))
88  continue;
89  const CTPPSDiamondDetId detid(it->first);
90  detids_.emplace_back(detid);
91  }
92 }
93 
94 //------------------------------------------------------------------------------
95 
97  DQMStore::IGetter& iGetter, int& db, int& sampic, int& channel, std::string path, CTPPSDiamondDetId detid) {
98  auto histDb = iGetter.get(path + "db");
99  auto histSampic = iGetter.get(path + "sampic");
100  auto histChannel = iGetter.get(path + "channel");
101 
102  if (histDb == nullptr) {
103  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
104  << "Failed to retrieve db for detid: " << detid;
105  return false;
106  }
107 
108  if (histSampic == nullptr) {
109  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
110  << "Failed to retrieve sampic for detid: " << detid;
111  return false;
112  }
113 
114  if (histChannel == nullptr) {
115  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
116  << "Failed to retrieve channel hwId for detid: " << detid;
117  return false;
118  }
119 
120  db = histDb->getIntValue();
121  sampic = histSampic->getIntValue();
122  channel = histChannel->getIntValue();
123 
124  return true;
125 }
126 //------------------------------------------------------------------------------
127 
129  std::unordered_map<uint32_t, dqm::reco::MonitorElement*> timeHisto;
130  std::string ch_name, path;
131 
132  pt::ptree node;
133  pt::read_json(jsonCalibFile_, node);
134  const std::string formula = node.get<std::string>("formula");
135 
136  for (const auto& detid : detids_) {
137  detid.channelName(path, CTPPSDiamondDetId::nPath);
138  detid.channelName(ch_name);
139  path = dqmDir_ + "/" + path + "/" + ch_name;
140  const auto chid = detid.rawId();
141 
142  int db, sampic, channel;
143  if (!getDbSampicChannel(iGetter, db, sampic, channel, path, detid))
144  continue;
145 
146  int ct = 0;
147  for (pt::ptree::value_type& par : node.get_child("parameters." + std::to_string(db))) {
148  double new_time_offset;
149  if (ct == 16 * (1 - sampic) + channel) { //flip the calibration - sampic 1 is first in json
150  double old_time_offset = par.second.get<double>("time_offset");
151 
152  timeHisto[chid] = iGetter.get(path);
153 
154  if (timeHisto[chid] == nullptr) {
155  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
156  << "Failed to retrieve time monitor for detid" << detid;
157  par.second.put<double>("time_offset", old_time_offset);
158  continue;
159  }
160 
161  if (min_entries_ > 0 && timeHisto[chid]->getEntries() < min_entries_) {
162  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
163  << "Not enough entries for channel (" << detid << "): " << timeHisto[chid]->getEntries() << " < "
164  << min_entries_ << ". Skipping calibration.";
165  par.second.put<double>("time_offset", old_time_offset);
166  continue;
167  }
168  new_time_offset = old_time_offset - timeHisto[chid]->getMean();
169  //scale x axis of the plots by calculated offset
170  timeHisto[chid]->getTH1F()->GetXaxis()->Set(
171  timeHisto[chid]->getTH1F()->GetXaxis()->GetNbins(),
172  timeHisto[chid]->getTH1F()->GetXaxis()->GetXmin() + new_time_offset, // new Xmin
173  timeHisto[chid]->getTH1F()->GetXaxis()->GetXmax() + new_time_offset); // new Xmax
174  timeHisto[chid]->getTH1F()->ResetStats();
175 
176  par.second.put<double>("time_offset", new_time_offset);
177  break;
178  }
179  ct++;
180  }
181  }
182  pt::write_json(jsonOutputPath_, node);
183 }
184 
185 //------------------------------------------------------------------------------
186 
189 
190  // book the parameters containers
193 
194  std::unordered_map<uint32_t, dqm::reco::MonitorElement*> timeHisto;
195  std::string rp_name, plane_name, ch_name, path;
196  const std::string& formula = calib.formula();
197 
198  for (const auto& detid : detids_) {
199  detid.channelName(path, CTPPSDiamondDetId::nPath);
200  detid.channelName(ch_name);
201  path = dqmDir_ + "/" + path + "/" + ch_name;
202  const auto chid = detid.rawId();
203 
204  int db, sampic, channel;
205  if (!getDbSampicChannel(iGetter, db, sampic, channel, path, detid))
206  continue;
207 
209  key.db = db;
210  key.sampic = sampic;
211  key.channel = channel;
212 
213  double timeOffset = calib.timeOffset(db, sampic, channel);
214  double timePrecision = calib.timePrecision(db, sampic, channel);
215  if (timeOffset == 0 && timePrecision == 0) {
216  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
217  << "No calibration found for db: " << db << " sampic: " << sampic << " channel: " << channel;
218  continue;
219  }
220 
221  int cell_ct = 0;
222  while (!calib.parameters(db, sampic, channel, cell_ct).empty()) {
223  auto parameters = calib.parameters(db, sampic, channel, cell_ct);
224  key.cell = cell_ct;
225  params[key] = parameters;
226  cell_ct++;
227  }
228 
229  key.cell = -1;
230 
231  time_info[key] = {timeOffset, timePrecision};
232  timeHisto[chid] = iGetter.get(path);
233  if (timeHisto[chid] == nullptr) {
234  edm::LogWarning("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
235  << "Failed to retrieve time monitor for detid: " << detid;
236  continue;
237  }
238 
239  if (min_entries_ > 0 && timeHisto[chid]->getEntries() < min_entries_) {
240  edm::LogInfo("PPSDiamondSampicTimingCalibrationPCLHarvester:dqmEndJob")
241  << "Not enough entries (" << detid << "): " << timeHisto[chid]->getEntries() << " < " << min_entries_
242  << ". Skipping calibration.";
243  continue;
244  }
245 
246  double new_time_offset = timeOffset - timeHisto[chid]->getMean();
247  //scale x axis of the plots by calculated offset
248  timeHisto[chid]->getTH1F()->GetXaxis()->Set(
249  timeHisto[chid]->getTH1F()->GetXaxis()->GetNbins(),
250  timeHisto[chid]->getTH1F()->GetXaxis()->GetXmin() + new_time_offset, // new Xmin
251  timeHisto[chid]->getTH1F()->GetXaxis()->GetXmax() + new_time_offset); // new Xmax
252  timeHisto[chid]->getTH1F()->ResetStats();
253 
254  time_info[key] = {new_time_offset, timePrecision};
255  }
256 
257  auto calibPPS = PPSTimingCalibration(formula, params, time_info);
258  // write the object
260  poolDbService->writeOneIOV(calibPPS, poolDbService->currentTime(), "PPSTimingCalibrationRcd_SAMPIC");
261 }
262 
263 //------------------------------------------------------------------------------
264 
266  iBooker.cd();
267  iBooker.setCurrentFolder(dqmDir_);
268  if (jsonCalibFile_.empty())
269  calibDb(iGetter);
270  else
271  calibJson(iGetter);
272 }
273 
274 //------------------------------------------------------------------------------
275 
278  desc.add<std::string>("timingCalibrationTag", "GlobalTag:PPSDiamondSampicCalibration")
279  ->setComment("input tag for timing calibration retrieval");
280  desc.add<std::string>("dqmDir", "AlCaReco/PPSDiamondSampicTimingCalibrationPCL")
281  ->setComment("input path for the various DQM plots");
282  desc.add<unsigned int>("minEntries", 1)->setComment("minimal number of hits to extract calibration");
283  desc.add<std::string>("jsonCalibFile", "")
284  ->setComment(
285  "input path for json file containing calibration, if none, calibration will be obtained from db instead");
286  desc.add<std::string>("jsonOutputPath", "offset_cal.json")->setComment("output path for the new json calibration");
287  descriptions.add("PPSDiamondSampicTimingCalibrationPCLHarvester", desc);
288 }
289 
std::map< Key, std::pair< double, double > > TimingMap
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
static std::string to_string(const XMLCh *ch)
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geomEsToken_
Helper structure for indexing calibration data.
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
Transition
Definition: Transition.h:12
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
bool getDbSampicChannel(DQMStore::IGetter &iGetter, int &db, int &sampic, int &channel, std::string ch_name, CTPPSDiamondDetId detid)
static bool check(unsigned int raw)
returns true if the raw ID is a PPS-timing one
Log< level::Info, false > LogInfo
void add(std::string const &label, ParameterSetDescription const &psetDescription)
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
HLT enums.
std::map< Key, std::vector< double > > ParametersMap
Detector ID class for CTPPS Timing Diamond detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bit...
Log< level::Warning, false > LogWarning
void beginRun(const edm::Run &, const edm::EventSetup &) override
Definition: Run.h:45
edm::ESGetToken< PPSTimingCalibration, PPSTimingCalibrationRcd > timingCalibrationToken_