CMS 3D CMS Logo

PPSTimingCalibrationPCLHarvester.cc
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This is a part of PPS offline software.
4  * Authors:
5  * Edoardo Bossini
6  * Piotr Maciej Cwiklicki
7  * Laurent Forthomme
8  *
9  ****************************************************************************/
10 
12 
19 
22 
25 
28 #include "TFitResult.h"
29 //------------------------------------------------------------------------------
30 
32 public:
34  void beginRun(const edm::Run&, const edm::EventSetup&) override;
35 
37 
38 private:
41  std::vector<CTPPSDiamondDetId> detids_;
44  const unsigned int min_entries_;
46  static constexpr double upper_limit_max_search_ = 20;
49  static constexpr double resolution_ = 0.1;
50  static constexpr double offset_ = 0.;
51  TF1 interp_;
52 };
53 
54 //------------------------------------------------------------------------------
55 
57  : geomEsToken_(esConsumes<edm::Transition::BeginRun>()),
58  dqmDir_(iConfig.getParameter<std::string>("dqmDir")),
59  formula_(iConfig.getParameter<std::string>("formula")),
60  min_entries_(iConfig.getParameter<unsigned int>("minEntries")),
61  threshold_fraction_of_max_(iConfig.getParameter<double>("thresholdFractionOfMax")),
62  interp_("interp", formula_.c_str(), 10.5, 25.) {
63  // first ensure DB output service is available
65  if (!poolDbService.isAvailable())
66  throw cms::Exception("PPSTimingCalibrationPCLHarvester") << "PoolDBService required";
67 
68  // constrain the min/max fit values
69  interp_.SetParLimits(1, 9., 15.);
70  interp_.SetParLimits(2, 0.2, 2.5);
71 }
72 
73 //------------------------------------------------------------------------------
74 
76  const auto& geom = iSetup.getData(geomEsToken_);
77  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
78  if (!CTPPSDiamondDetId::check(it->first))
79  continue;
80  const CTPPSDiamondDetId detid(it->first);
81  detids_.emplace_back(detid);
82  }
83 }
84 
85 //------------------------------------------------------------------------------
86 
88  // book the parameters containers
91 
92  iGetter.cd();
93  iGetter.setCurrentFolder(dqmDir_);
94 
95  // compute the fit parameters for all monitored channels
97  std::string ch_name;
98  for (const auto& detid : detids_) {
99  detid.channelName(ch_name);
100  const auto chid = detid.rawId();
102  (int)detid.arm(), (int)detid.station(), (int)detid.plane(), (int)detid.channel()};
103 
104  calib_params[key] = {0, 0, 0, 0};
105  calib_time[key] = std::make_pair(offset_, resolution_);
106 
107  hists.leadingTime[chid] = iGetter.get(dqmDir_ + "/t_" + ch_name);
108  if (hists.leadingTime[chid] == nullptr) {
109  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
110  << "Failed to retrieve leading time monitor for channel (" << detid << ").";
111  continue;
112  }
113  hists.toT[chid] = iGetter.get(dqmDir_ + "/tot_" + ch_name);
114  if (hists.toT[chid] == nullptr) {
115  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
116  << "Failed to retrieve time over threshold monitor for channel (" << detid << ").";
117  continue;
118  }
119  hists.leadingTimeVsToT[chid] = iGetter.get(dqmDir_ + "/tvstot_" + ch_name);
120  if (hists.leadingTimeVsToT[chid] == nullptr) {
121  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
122  << "Failed to retrieve leading time vs. time over threshold monitor for channel (" << detid << ").";
123  continue;
124  }
125  if (min_entries_ > 0 && hists.leadingTimeVsToT[chid]->getEntries() < min_entries_) {
126  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
127  << "Not enough entries for channel (" << detid << "): " << hists.leadingTimeVsToT[chid]->getEntries() << " < "
128  << min_entries_ << ". Skipping calibration.";
129  continue;
130  }
131 
132  //find max
133  int max_bin_pos = 1;
134  for (int i = 0; i < hists.toT[chid]->getNbinsX(); i++) {
135  double bin_value = hists.toT[chid]->getBinContent(i);
136  int bin_x_pos = hists.toT[chid]->getTH1()->GetXaxis()->GetBinCenter(i);
137  if (bin_x_pos > upper_limit_max_search_)
138  break;
139  if (bin_value > hists.toT[chid]->getBinContent(max_bin_pos))
140  max_bin_pos = i;
141  }
142  //find ranges
143  int upper_limit_pos = max_bin_pos;
144  int lower_limit_pos = max_bin_pos;
145  double threshold = threshold_fraction_of_max_ * hists.toT[chid]->getBinContent(max_bin_pos);
146  while (hists.toT[chid]->getTH1()->GetXaxis()->GetBinCenter(upper_limit_pos) < upper_limit_range_search_) {
147  upper_limit_pos++;
148  if (hists.toT[chid]->getBinContent(upper_limit_pos) < threshold)
149  break;
150  }
151  while (hists.toT[chid]->getTH1()->GetXaxis()->GetBinCenter(lower_limit_pos) > lower_limit_range_search_) {
152  lower_limit_pos--;
153  if (hists.toT[chid]->getBinContent(lower_limit_pos) < threshold)
154  break;
155  }
156  double upper_tot_range = hists.toT[chid]->getTH1()->GetXaxis()->GetBinCenter(upper_limit_pos);
157  double lower_tot_range = hists.toT[chid]->getTH1()->GetXaxis()->GetBinCenter(lower_limit_pos);
158 
159  { // scope for x-profile
160 
161  std::string ch_name;
162  detid.channelName(ch_name);
163  auto profile = iBooker.bookProfile(ch_name + "_prof_x", ch_name + "_prof_x", 240, 0., 60., 450, -20., 25.);
164 
165  std::unique_ptr<TProfile> prof(hists.leadingTimeVsToT[chid]->getTH2F()->ProfileX("_prof_x", 1, -1));
166  *(profile->getTProfile()) = *((TProfile*)prof->Clone());
167  profile->getTProfile()->SetTitle(ch_name.c_str());
168  profile->getTProfile()->SetName(ch_name.c_str());
169 
170  interp_.SetParameters(hists.leadingTime[chid]->getRMS(),
171  hists.toT[chid]->getMean(),
172  0.8,
173  hists.leadingTime[chid]->getMean() - hists.leadingTime[chid]->getRMS());
174  const auto& res = profile->getTProfile()->Fit(&interp_, "B+", "", lower_tot_range, upper_tot_range);
175  if (!(bool)res) {
176  calib_params[key] = {
177  interp_.GetParameter(0), interp_.GetParameter(1), interp_.GetParameter(2), interp_.GetParameter(3)};
178  calib_time[key] =
179  std::make_pair(offset_, resolution_); // hardcoded offset/resolution placeholder for the time being
180  // can possibly do something with interp_.GetChiSquare() in the near future
181 
182  } else
183  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
184  << "Fit did not converge for channel (" << detid << ").";
185  }
186  }
187 
188  // fill the DB object record
189  PPSTimingCalibration calib(formula_, calib_params, calib_time);
190 
191  // write the object
193  poolDbService->writeOneIOV(calib, poolDbService->currentTime(), "PPSTimingCalibrationRcd_HPTDC");
194 }
195 
196 //------------------------------------------------------------------------------
197 
200  desc.add<std::string>("dqmDir", "AlCaReco/PPSTimingCalibrationPCL")
201  ->setComment("input path for the various DQM plots");
202  desc.add<std::string>("formula", "[0]/(exp((x-[1])/[2])+1)+[3]")
203  ->setComment("interpolation formula for the time walk component");
204  desc.add<unsigned int>("minEntries", 100)->setComment("minimal number of hits to extract calibration");
205  desc.add<double>("thresholdFractionOfMax", 0.05)
206  ->setComment("threshold for TOT fit, defined as percent of max count in 1D TOT");
207  descriptions.addWithDefaultLabel(desc);
208 }
209 
std::map< Key, std::pair< double, double > > TimingMap
PPSTimingCalibrationPCLHarvester(const edm::ParameterSet &)
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
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
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geomEsToken_
static void fillDescriptions(edm::ConfigurationDescriptions &)
Definition: Electron.h:6
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:408
Helper structure for indexing calibration data.
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
Transition
Definition: Transition.h:12
key
prepare the HTCondor submission files and eventually submit them
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static bool check(unsigned int raw)
returns true if the raw ID is a PPS-timing one
Log< level::Info, false > LogInfo
void beginRun(const edm::Run &, const edm::EventSetup &) override
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...
bool isAvailable() const
Definition: Service.h:40
Log< level::Warning, false > LogWarning
Definition: Run.h:45