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  if (detid.station() == 1) // for the time being, only compute for this station (run 2 diamond)
77  detids_.emplace_back(detid);
78  }
79 }
80 
81 //------------------------------------------------------------------------------
82 
84  // book the parameters containers
87 
88  iGetter.cd();
89  iGetter.setCurrentFolder(dqmDir_);
90 
91  // compute the fit parameters for all monitored channels
93  std::string ch_name;
94  for (const auto& detid : detids_) {
95  detid.channelName(ch_name);
96  const auto chid = detid.rawId();
98  (int)detid.arm(), (int)detid.station(), (int)detid.plane(), (int)detid.channel()};
99 
100  calib_params[key] = {0, 0, 0, 0};
101  calib_time[key] = std::make_pair(offset_, resolution_);
102 
103  hists.leadingTime[chid] = iGetter.get(dqmDir_ + "/t_" + ch_name);
104  if (hists.leadingTime[chid] == nullptr) {
105  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
106  << "Failed to retrieve leading time monitor for channel (" << detid << ").";
107  continue;
108  }
109  hists.toT[chid] = iGetter.get(dqmDir_ + "/tot_" + ch_name);
110  if (hists.toT[chid] == nullptr) {
111  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
112  << "Failed to retrieve time over threshold monitor for channel (" << detid << ").";
113  continue;
114  }
115  hists.leadingTimeVsToT[chid] = iGetter.get(dqmDir_ + "/tvstot_" + ch_name);
116  if (hists.leadingTimeVsToT[chid] == nullptr) {
117  edm::LogInfo("PPSTimingCalibrationPCLHarvester:dqmEndJob")
118  << "Failed to retrieve leading time vs. time over threshold monitor for channel (" << detid << ").";
119  continue;
120  }
121  if (min_entries_ > 0 && hists.leadingTimeVsToT[chid]->getEntries() < min_entries_) {
122  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
123  << "Not enough entries for channel (" << detid << "): " << hists.leadingTimeVsToT[chid]->getEntries() << " < "
124  << min_entries_ << ". Skipping calibration.";
125  continue;
126  }
127  const double upper_tot_range = hists.toT[chid]->getMean() + 2.5;
128  { // scope for x-profile
129 
130  std::string ch_name;
131  detid.channelName(ch_name);
132  auto profile = iBooker.bookProfile(ch_name + "_prof_x", ch_name + "_prof_x", 240, 0., 60., 450, -20., 25.);
133 
134  std::unique_ptr<TProfile> prof(hists.leadingTimeVsToT[chid]->getTH2F()->ProfileX("_prof_x", 1, -1));
135  *(profile->getTProfile()) = *((TProfile*)prof->Clone());
136  profile->getTProfile()->SetTitle(ch_name.c_str());
137  profile->getTProfile()->SetName(ch_name.c_str());
138 
139  interp_.SetParameters(hists.leadingTime[chid]->getRMS(),
140  hists.toT[chid]->getMean(),
141  0.8,
142  hists.leadingTime[chid]->getMean() - hists.leadingTime[chid]->getRMS());
143  const auto& res = profile->getTProfile()->Fit(&interp_, "B+", "", 10.4, upper_tot_range);
144  if (!(bool)res) {
145  calib_params[key] = {
146  interp_.GetParameter(0), interp_.GetParameter(1), interp_.GetParameter(2), interp_.GetParameter(3)};
147  calib_time[key] =
148  std::make_pair(offset_, resolution_); // hardcoded offset/resolution placeholder for the time being
149  // can possibly do something with interp_.GetChiSquare() in the near future
150 
151  } else
152  edm::LogWarning("PPSTimingCalibrationPCLHarvester:dqmEndJob")
153  << "Fit did not converge for channel (" << detid << ").";
154  }
155  }
156 
157  // fill the DB object record
158  PPSTimingCalibration calib(formula_, calib_params, calib_time);
159 
160  // write the object
162  poolDbService->writeOneIOV(calib, poolDbService->currentTime(), "PPSTimingCalibrationRcd_HPTDC");
163 }
164 
165 //------------------------------------------------------------------------------
166 
169  desc.add<std::string>("dqmDir", "AlCaReco/PPSTimingCalibrationPCL")
170  ->setComment("input path for the various DQM plots");
171  desc.add<std::string>("formula", "[0]/(exp((x-[1])/[2])+1)+[3]")
172  ->setComment("interpolation formula for the time walk component");
173  desc.add<unsigned int>("minEntries", 100)->setComment("minimal number of hits to extract calibration");
174  descriptions.addWithDefaultLabel(desc);
175 }
176 
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
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geomEsToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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
uint32_t station() const
Definition: CTPPSDetId.h:58
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:673
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