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_;
45  static constexpr double resolution_ = 0.1;
46  static constexpr double offset_ = 0.;
47  TF1 interp_;
48 };
49 
50 //------------------------------------------------------------------------------
51 
53  : geomEsToken_(esConsumes<edm::Transition::BeginRun>()),
54  dqmDir_(iConfig.getParameter<std::string>("dqmDir")),
55  formula_(iConfig.getParameter<std::string>("formula")),
56  min_entries_(iConfig.getParameter<unsigned int>("minEntries")),
57  interp_("interp", formula_.c_str(), 10.5, 25.) {
58  // first ensure DB output service is available
60  if (!poolDbService.isAvailable())
61  throw cms::Exception("PPSTimingCalibrationPCLHarvester") << "PoolDBService required";
62 
63  // constrain the min/max fit values
64  interp_.SetParLimits(1, 9., 15.);
65  interp_.SetParLimits(2, 0.2, 2.5);
66 }
67 
68 //------------------------------------------------------------------------------
69 
71  const auto& geom = iSetup.getData(geomEsToken_);
72  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
73  if (!CTPPSDiamondDetId::check(it->first))
74  continue;
75  const CTPPSDiamondDetId detid(it->first);
76  detids_.emplace_back(detid);
77  }
78 }
79 
80 //------------------------------------------------------------------------------
81 
83  // book the parameters containers
86 
87  iGetter.cd();
88  iGetter.setCurrentFolder(dqmDir_);
89 
90  // compute the fit parameters for all monitored channels
92  std::string ch_name;
93  for (const auto& detid : detids_) {
94  detid.channelName(ch_name);
95  const auto chid = detid.rawId();
97  (int)detid.arm(), (int)detid.station(), (int)detid.plane(), (int)detid.channel()};
98 
99  calib_params[key] = {0, 0, 0, 0};
100  calib_time[key] = std::make_pair(offset_, resolution_);
101 
102  hists.leadingTime[chid] = iGetter.get(dqmDir_ + "/t_" + ch_name);
103  if (hists.leadingTime[chid] == nullptr) {
104  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
105  << "Failed to retrieve leading time monitor for channel (" << detid << ").";
106  continue;
107  }
108  hists.toT[chid] = iGetter.get(dqmDir_ + "/tot_" + ch_name);
109  if (hists.toT[chid] == nullptr) {
110  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
111  << "Failed to retrieve time over threshold monitor for channel (" << detid << ").";
112  continue;
113  }
114  hists.leadingTimeVsToT[chid] = iGetter.get(dqmDir_ + "/tvstot_" + ch_name);
115  if (hists.leadingTimeVsToT[chid] == nullptr) {
116  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
117  << "Failed to retrieve leading time vs. time over threshold monitor for channel (" << detid << ").";
118  continue;
119  }
120  if (min_entries_ > 0 && hists.leadingTimeVsToT[chid]->getEntries() < min_entries_) {
121  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
122  << "Not enough entries for channel (" << detid << "): " << hists.leadingTimeVsToT[chid]->getEntries() << " < "
123  << min_entries_ << ". Skipping calibration.";
124  continue;
125  }
126  const double upper_tot_range = hists.toT[chid]->getMean() + 2.5;
127  { // scope for x-profile
128 
129  std::string ch_name;
130  detid.channelName(ch_name);
131  auto profile = iBooker.bookProfile(ch_name + "_prof_x", ch_name + "_prof_x", 240, 0., 60., 450, -20., 25.);
132 
133  std::unique_ptr<TProfile> prof(hists.leadingTimeVsToT[chid]->getTH2F()->ProfileX("_prof_x", 1, -1));
134  *(profile->getTProfile()) = *((TProfile*)prof->Clone());
135  profile->getTProfile()->SetTitle(ch_name.c_str());
136  profile->getTProfile()->SetName(ch_name.c_str());
137 
138  interp_.SetParameters(hists.leadingTime[chid]->getRMS(),
139  hists.toT[chid]->getMean(),
140  0.8,
141  hists.leadingTime[chid]->getMean() - hists.leadingTime[chid]->getRMS());
142  const auto& res = profile->getTProfile()->Fit(&interp_, "B+", "", 10.4, upper_tot_range);
143  if (!(bool)res) {
144  calib_params[key] = {
145  interp_.GetParameter(0), interp_.GetParameter(1), interp_.GetParameter(2), interp_.GetParameter(3)};
146  calib_time[key] =
147  std::make_pair(offset_, resolution_); // hardcoded offset/resolution placeholder for the time being
148  // can possibly do something with interp_.GetChiSquare() in the near future
149 
150  } else
151  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
152  << "Fit did not converge for channel (" << detid << ").";
153  }
154  }
155 
156  // fill the DB object record
157  PPSTimingCalibration calib(formula_, calib_params, calib_time);
158 
159  // write the object
161  poolDbService->writeOneIOV(calib, poolDbService->currentTime(), "PPSTimingCalibrationRcd_HPTDC");
162 }
163 
164 //------------------------------------------------------------------------------
165 
168  desc.add<std::string>("dqmDir", "AlCaReco/PPSTimingCalibrationPCL")
169  ->setComment("input path for the various DQM plots");
170  desc.add<std::string>("formula", "[0]/(exp((x-[1])/[2])+1)+[3]")
171  ->setComment("interpolation formula for the time walk component");
172  desc.add<unsigned int>("minEntries", 100)->setComment("minimal number of hits to extract calibration");
173  descriptions.addWithDefaultLabel(desc);
174 }
175 
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:399
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
#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