CMS 3D CMS Logo

PPSAlignmentHarvester.cc
Go to the documentation of this file.
1 /****************************************************************************
2 * Authors:
3 * Jan Kašpar (jan.kaspar@gmail.com)
4 * Mateusz Kocot (mateuszkocot99@gmail.com)
5 ****************************************************************************/
6 
10 
16 
18 
22 
25 
27 
28 #include <memory>
29 #include <map>
30 #include <vector>
31 #include <string>
32 #include <fstream>
33 #include <iomanip>
34 #include <cmath>
35 #include <utility>
36 
37 #include "TH1D.h"
38 #include "TH2D.h"
39 #include "TGraph.h"
40 #include "TGraphErrors.h"
41 #include "TF1.h"
42 #include "TProfile.h"
43 #include "TFile.h"
44 #include "TKey.h"
45 #include "TSpline.h"
46 #include "TCanvas.h"
47 
48 //----------------------------------------------------------------------------------------------------
49 
51 public:
53  ~PPSAlignmentHarvester() override;
54 
55  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
56 
57 private:
58  void dqmEndJob(DQMStore::IBooker& iBooker, DQMStore::IGetter& iGetter) override;
59  void dqmEndRun(DQMStore::IBooker& iBooker,
60  DQMStore::IGetter& iGetter,
61  edm::Run const& iRun,
62  edm::EventSetup const& iSetup) override;
63 
64  // ------------ x alignment ------------
65  std::unique_ptr<TGraphErrors> buildGraphFromVector(const std::vector<PPSAlignmentConfiguration::PointErrors>& pv);
66  std::unique_ptr<TGraphErrors> buildGraphFromMonitorElements(DQMStore::IGetter& iGetter,
68  const std::vector<MonitorElement*>& mes,
69  const unsigned int fitProfileMinBinEntries,
70  const unsigned int fitProfileMinNReasonable);
71  void doMatch(DQMStore::IBooker& iBooker,
74  TGraphErrors* g_ref,
75  TGraphErrors* g_test,
77  const double sh_min,
78  const double sh_max,
79  double& sh_best,
80  double& sh_best_unc);
81 
82  void xAlignment(DQMStore::IBooker& iBooker,
83  DQMStore::IGetter& iGetter,
85  const PPSAlignmentConfiguration& cfg_ref);
86 
87  std::map<unsigned int, double> sh_x_map_;
88 
89  // ------------ x alignment relative ------------
91 
92  // ------------ y alignment ------------
93  static double findMax(const TF1* ff_fit);
94  TH1D* buildModeGraph(DQMStore::IBooker& iBooker,
95  const MonitorElement* h2_y_vs_x,
98 
100 
101  // ------------ other member data and methods ------------
102  static void writeCutPlot(
103  TH2D* h, const double a, const double c, const double si, const double n_si, const std::string& label);
104  static std::unique_ptr<TH1D> getTH1DFromTGraphErrors(TGraphErrors* graph,
105  const std::string& title = "",
106  const std::string& labels = "",
107  int n = -1,
108  double binWidth = -1.,
109  double min = -1.);
110 
113 
114  // variables from parameters
116  const std::vector<std::string> sequence_;
117  const bool overwriteShX_;
121  const std::pair<double, double> xCorrRange_;
122  const std::pair<double, double> yCorrRange_;
123  const bool debug_;
124 
125  // other class variables
126  std::unique_ptr<TFile> debugFile_;
127  std::ofstream textResultsFile_;
128  int seqPos = 1; // position in sequence_
129 
131 
134 
137 };
138 
139 // -------------------------------- DQMEDHarvester methods --------------------------------
140 
143  edm::ESInputTag("", ""))),
145  edm::ESInputTag("", "reference"))),
146  dqmDir_(iConfig.getParameter<std::string>("dqm_dir")),
147  sequence_(iConfig.getParameter<std::vector<std::string>>("sequence")),
148  overwriteShX_(iConfig.getParameter<bool>("overwrite_sh_x")),
149  writeSQLiteResults_(iConfig.getParameter<bool>("write_sqlite_results")),
150  xAliRelFinalSlopeFixed_(iConfig.getParameter<bool>("x_ali_rel_final_slope_fixed")),
151  yAliFinalSlopeFixed_(iConfig.getParameter<bool>("y_ali_final_slope_fixed")),
152  xCorrRange_(std::make_pair(iConfig.getParameter<double>("x_corr_min") / 1000.,
153  iConfig.getParameter<double>("x_corr_max") / 1000.)), // um -> mm
154  yCorrRange_(std::make_pair(iConfig.getParameter<double>("y_corr_min") / 1000.,
155  iConfig.getParameter<double>("y_corr_max") / 1000.)), // um -> mm
156  debug_(iConfig.getParameter<bool>("debug")) {
157  auto textResultsPath = iConfig.getParameter<std::string>("text_results_path");
158  if (!textResultsPath.empty()) {
159  textResultsFile_.open(textResultsPath, std::ios::out | std::ios::trunc);
160  }
161  if (debug_) {
162  debugFile_ = std::make_unique<TFile>("debug_harvester.root", "recreate");
163  }
164 
165  edm::LogInfo("PPSAlignmentHarvester").log([&](auto& li) {
166  li << "parameters:\n";
167  li << "* dqm_dir: " << dqmDir_ << "\n";
168  li << "* sequence:\n";
169  for (unsigned int i = 0; i < sequence_.size(); i++) {
170  li << " " << i + 1 << ": " << sequence_[i] << "\n";
171  }
172  li << "* overwrite_sh_x: " << std::boolalpha << overwriteShX_ << "\n";
173  li << "* text_results_path: " << textResultsPath << "\n";
174  li << "* write_sqlite_results: " << std::boolalpha << writeSQLiteResults_ << "\n";
175  li << "* x_ali_rel_final_slope_fixed: " << std::boolalpha << xAliRelFinalSlopeFixed_ << "\n";
176  li << "* y_ali_final_slope_fixed: " << std::boolalpha << yAliFinalSlopeFixed_ << "\n";
177  // print in um
178  li << "* x_corr_min: " << std::fixed << xCorrRange_.first * 1000. << ", x_corr_max: " << xCorrRange_.second * 1000.
179  << "\n";
180  // print in um
181  li << "* y_corr_min: " << std::fixed << yCorrRange_.first * 1000. << ", y_corr_max: " << yCorrRange_.second * 1000.;
182  li << "* debug: " << std::boolalpha << debug_ << "\n";
183  });
184 }
185 
187  if (textResultsFile_.is_open()) {
188  textResultsFile_.close();
189  }
190 }
191 
194 
195  desc.add<std::string>("dqm_dir", "AlCaReco/PPSAlignment");
196  desc.add<std::vector<std::string>>("sequence", {"x_alignment", "x_alignment_relative", "y_alignment"});
197  desc.add<bool>("overwrite_sh_x", true);
198  desc.add<std::string>("text_results_path", "./alignment_results.txt");
199  desc.add<bool>("write_sqlite_results", false);
200  desc.add<bool>("x_ali_rel_final_slope_fixed", true);
201  desc.add<bool>("y_ali_final_slope_fixed", true);
202  desc.add<double>("x_corr_min", -1'000'000.);
203  desc.add<double>("x_corr_max", 1'000'000.);
204  desc.add<double>("y_corr_min", -1'000'000.);
205  desc.add<double>("y_corr_max", 1'000'000.);
206  desc.add<bool>("debug", false);
207 
208  descriptions.addWithDefaultLabel(desc);
209 }
210 
212 
214  DQMStore::IGetter& iGetter,
215  edm::Run const& iRun,
216  edm::EventSetup const& iSetup) {
217  const auto& cfg = iSetup.getData(esTokenTest_);
218 
219  const auto& cfg_ref = iSetup.getData(esTokenReference_);
220 
221  // setting default sh_x values from config
222  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
223  for (const auto& rpc : {sc.rp_N_, sc.rp_F_}) {
224  sh_x_map_[rpc.id_] = rpc.sh_x_;
225  }
226  }
227  edm::LogInfo("PPSAlignmentHarvester").log([&](auto& li) {
228  li << "Setting sh_x from config of:\n";
229  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
230  for (const auto& rpc : {sc.rp_N_, sc.rp_F_}) {
231  li << " " << rpc.name_ << " to " << std::fixed << std::setprecision(3) << rpc.sh_x_;
232  if (rpc.name_ != "R_2_F")
233  li << "\n";
234  }
235  }
236  });
237 
238  bool doXAli = false, doXAliRel = false, doYAli = false;
239  for (const std::string& aliMethod : sequence_) {
240  if (aliMethod == "x_alignment") {
241  xAlignment(iBooker, iGetter, cfg, cfg_ref);
242  doXAli = true;
243  } else if (aliMethod == "x_alignment_relative") {
244  xAlignmentRelative(iBooker, iGetter, cfg);
245  doXAliRel = true;
246  } else if (aliMethod == "y_alignment") {
247  yAlignment(iBooker, iGetter, cfg);
248  doYAli = true;
249  } else
250  edm::LogError("PPSAlignmentHarvester") << aliMethod << " is a wrong method name.";
251  seqPos++;
252  }
253 
254  // merge results from all the specified methods
255  CTPPSRPAlignmentCorrectionsData finalResults;
256  if (doXAli) { // x alignment
257  finalResults.addCorrections(xAliResults_);
258  if (doXAliRel) { // merge with x alignment relative
259  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
260  // extract shifts
261  double d_x_N = xAliResults_.getRPCorrection(sc.rp_N_.id_).getShX();
262  double d_x_F = xAliResults_.getRPCorrection(sc.rp_F_.id_).getShX();
263 
264  double d_x_rel_N, d_x_rel_F;
266  d_x_rel_N = xAliRelResultsSlopeFixed_.getRPCorrection(sc.rp_N_.id_).getShX();
267  d_x_rel_F = xAliRelResultsSlopeFixed_.getRPCorrection(sc.rp_F_.id_).getShX();
268  } else {
269  d_x_rel_N = xAliRelResults_.getRPCorrection(sc.rp_N_.id_).getShX();
270  d_x_rel_F = xAliRelResults_.getRPCorrection(sc.rp_F_.id_).getShX();
271  }
272 
273  // merge the results
274  double b = d_x_rel_N - d_x_rel_F;
275  double xCorrRel = b + d_x_F - d_x_N;
276 
277  CTPPSRPAlignmentCorrectionData corrRelN(xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
278  finalResults.addRPCorrection(sc.rp_N_.id_, corrRelN);
279  CTPPSRPAlignmentCorrectionData corrRelF(-xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
280  finalResults.addRPCorrection(sc.rp_F_.id_, corrRelF);
281  }
282  }
283  }
284  if (doYAli) { // y alignment
285  if (yAliFinalSlopeFixed_) {
287  } else {
288  finalResults.addCorrections(yAliResults_);
289  }
290  }
291 
292  // check if the results are within the reasonability ranges xCorrRange and yCorrRange
293  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
294  for (const auto& rpc : {sc.rp_F_, sc.rp_N_}) {
295  auto& rpResults = finalResults.getRPCorrection(rpc.id_);
296 
297  if (!(xCorrRange_.first <= rpResults.getShX() && rpResults.getShX() <= xCorrRange_.second)) {
298  edm::LogWarning("PPSAlignmentHarvester")
299  << "The horizontal shift of " << rpc.name_ << " (" << std::fixed << std::setw(9) << std::setprecision(1)
300  << rpResults.getShX() * 1000. << " um) outside of the reasonability range. Setting it to 0.";
301  rpResults.setShX(0.);
302  rpResults.setShXUnc(0.);
303  }
304 
305  if (!(yCorrRange_.first <= rpResults.getShY() && rpResults.getShY() <= yCorrRange_.second)) {
306  edm::LogWarning("PPSAlignmentHarvester")
307  << "The vertical shift of " << rpc.name_ << " (" << std::fixed << std::setw(9) << std::setprecision(1)
308  << rpResults.getShY() * 1000. << " um) outside of the reasonability range. Setting it to 0.";
309  rpResults.setShY(0.);
310  rpResults.setShYUnc(0.);
311  }
312  }
313  }
314 
315  // print the text results
316  edm::LogInfo("PPSAlignmentHarvester") << "final merged results:\n" << finalResults;
317 
318  if (textResultsFile_.is_open()) {
319  textResultsFile_ << "final merged results:\n" << finalResults;
320  }
321 
322  // if requested, store the results in a DB object
323  if (writeSQLiteResults_) {
325  if (poolDbService.isAvailable()) {
326  poolDbService->writeOneIOV(finalResults, poolDbService->currentTime(), "CTPPSRPAlignmentCorrectionsDataRcd");
327  } else {
328  edm::LogWarning("PPSAlignmentHarvester")
329  << "Could not store the results in a DB object. PoolDBService not available.";
330  }
331  }
332 
333  // if debug_, save nice-looking cut plots with the worker data in the debug ROOT file
334  if (debug_) {
335  TDirectory* cutsDir = debugFile_->mkdir("cuts");
336  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
337  TDirectory* sectorDir = cutsDir->mkdir(sc.name_.c_str());
338 
339  gDirectory = sectorDir->mkdir("cut_h");
340  auto* h2_cut_h_bef_monitor = iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/cuts/cut_h/h2_cut_h_bef");
341  auto* h2_cut_h_aft_monitor = iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/cuts/cut_h/h2_cut_h_aft");
342  writeCutPlot(
343  h2_cut_h_bef_monitor->getTH2D(), sc.cut_h_a_, sc.cut_h_c_, cfg.n_si(), sc.cut_h_si_, "canvas_before");
344  writeCutPlot(h2_cut_h_aft_monitor->getTH2D(), sc.cut_h_a_, sc.cut_h_c_, cfg.n_si(), sc.cut_h_si_, "canvas_after");
345 
346  gDirectory = sectorDir->mkdir("cut_v");
347  auto* h2_cut_v_bef_monitor = iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/cuts/cut_v/h2_cut_v_bef");
348  auto* h2_cut_v_aft_monitor = iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/cuts/cut_v/h2_cut_v_aft");
349  writeCutPlot(
350  h2_cut_v_bef_monitor->getTH2D(), sc.cut_v_a_, sc.cut_v_c_, cfg.n_si(), sc.cut_v_si_, "canvas_before");
351  writeCutPlot(h2_cut_v_aft_monitor->getTH2D(), sc.cut_v_a_, sc.cut_v_c_, cfg.n_si(), sc.cut_v_si_, "canvas_after");
352  }
353  }
354 }
355 
356 // -------------------------------- x alignment methods --------------------------------
357 
358 // Builds graph from a vector of points (with errors).
359 std::unique_ptr<TGraphErrors> PPSAlignmentHarvester::buildGraphFromVector(
360  const std::vector<PPSAlignmentConfiguration::PointErrors>& pv) {
361  auto g = std::make_unique<TGraphErrors>();
362 
363  for (unsigned int i = 0; i < pv.size(); i++) {
364  const auto& p = pv[i];
365  g->SetPoint(i, p.x_, p.y_);
366  g->SetPointError(i, p.ex_, p.ey_);
367  }
368  g->Sort();
369 
370  return g;
371 }
372 
373 // Builds a TGraphErrors from slice plots represented as MonitorElements.
375  DQMStore::IGetter& iGetter,
377  const std::vector<MonitorElement*>& mes,
378  const unsigned int fitProfileMinBinEntries,
379  const unsigned int fitProfileMinNReasonable) {
380  auto g = std::make_unique<TGraphErrors>();
381 
382  for (auto* me : mes) {
383  if (me->getName() == "h_y") // find "h_y"
384  {
385  // retrieve parent directory
386  std::string parentPath = me->getPathname();
387  size_t parentPos = parentPath.substr(0, parentPath.size() - 1).find_last_of('/') + 1;
388  std::string parentName = parentPath.substr(parentPos);
389  size_t d = parentName.find('-');
390  const double x_min = std::stod(parentName.substr(0, d));
391  const double x_max = std::stod(parentName.substr(d + 1));
392 
393  TH1D* h_y = me->getTH1D();
394 
395  // collect "p_y_diffFN_vs_y" corresponding to found "h_y"
396  auto* p_y_diffFN_vs_y_monitor = iGetter.get(parentPath + "p_y_diffFN_vs_y");
397  if (p_y_diffFN_vs_y_monitor == nullptr) {
398  edm::LogWarning("PPSAlignmentHarvester") << "[x_alignment] could not find p_y_diffFN_vs_y in: " << parentPath;
399  continue;
400  }
401  TProfile* p_y_diffFN_vs_y = p_y_diffFN_vs_y_monitor->getTProfile();
402 
403  double y_cen = h_y->GetMean() + rpc.y_cen_add_;
404  double y_width = h_y->GetRMS() * rpc.y_width_mult_;
405 
406  double sl, sl_unc;
407  int fr = alig_utils::fitProfile(
408  p_y_diffFN_vs_y, y_cen, y_width, fitProfileMinBinEntries, fitProfileMinNReasonable, sl, sl_unc);
409  if (fr != 0)
410  continue;
411 
412  if (debug_)
413  p_y_diffFN_vs_y->Write(parentName.c_str());
414 
415  int idx = g->GetN();
416  g->SetPoint(idx, (x_max + x_min) / 2., sl);
417  g->SetPointError(idx, (x_max - x_min) / 2., sl_unc);
418  }
419  }
420  g->Sort();
421 
422  return g;
423 }
424 
425 // Matches reference data with test data.
429  TGraphErrors* g_ref,
430  TGraphErrors* g_test,
432  const double sh_min,
433  const double sh_max,
434  double& sh_best,
435  double& sh_best_unc) {
436  const auto range_test = cfg.alignment_x_meth_o_ranges().at(rpc.id_);
437 
438  // print config
439  edm::LogInfo("PPSAlignmentHarvester") << std::fixed << std::setprecision(3) << "[x_alignment] "
440  << "ref: x_min = " << range_ref.x_min_ << ", x_max = " << range_ref.x_max_
441  << "\n"
442  << "test: x_min = " << range_test.x_min_ << ", x_max = " << range_test.x_max_;
443 
444  // make spline from g_ref
445  auto s_ref = std::make_unique<TSpline3>("s_ref", g_ref->GetX(), g_ref->GetY(), g_ref->GetN());
446 
447  // book match-quality graphs
448  auto g_n_points = std::make_unique<TGraph>();
449  g_n_points->SetName("g_n_points");
450  g_n_points->SetTitle(";sh;N");
451  auto g_chi_sq = std::make_unique<TGraph>();
452  g_chi_sq->SetName("g_chi_sq");
453  g_chi_sq->SetTitle(";sh;S2");
454  auto g_chi_sq_norm = std::make_unique<TGraph>();
455  g_chi_sq_norm->SetName("g_chi_sq_norm");
456  g_chi_sq_norm->SetTitle(";sh;S2 / N");
457 
458  // optimalisation variables
459  double S2_norm_best = 1E100;
460 
461  for (double sh = sh_min; sh <= sh_max; sh += cfg.x_ali_sh_step()) {
462  // calculate chi^2
463  int n_points = 0;
464  double S2 = 0.;
465 
466  for (int i = 0; i < g_test->GetN(); ++i) {
467  const double x_test = g_test->GetX()[i];
468  const double y_test = g_test->GetY()[i];
469  const double y_test_unc = g_test->GetErrorY(i);
470 
471  const double x_ref = x_test + sh;
472 
473  if (x_ref < range_ref.x_min_ || x_ref > range_ref.x_max_ || x_test < range_test.x_min_ ||
474  x_test > range_test.x_max_)
475  continue;
476 
477  const double y_ref = s_ref->Eval(x_ref);
478 
479  int js = -1, jg = -1;
480  double xs = -1E100, xg = +1E100;
481  for (int j = 0; j < g_ref->GetN(); ++j) {
482  const double x = g_ref->GetX()[j];
483  if (x < x_ref && x > xs) {
484  xs = x;
485  js = j;
486  }
487  if (x > x_ref && x < xg) {
488  xg = x;
489  jg = j;
490  }
491  }
492  if (jg == -1)
493  jg = js;
494 
495  const double y_ref_unc = (g_ref->GetErrorY(js) + g_ref->GetErrorY(jg)) / 2.;
496 
497  n_points++;
498  const double S2_inc = pow(y_test - y_ref, 2.) / (y_ref_unc * y_ref_unc + y_test_unc * y_test_unc);
499  S2 += S2_inc;
500  }
501 
502  // update best result
503  double S2_norm = S2 / n_points;
504 
505  if (S2_norm < S2_norm_best) {
506  S2_norm_best = S2_norm;
507  sh_best = sh;
508  }
509 
510  // fill in graphs
511  int idx = g_n_points->GetN();
512  g_n_points->SetPoint(idx, sh, n_points);
513  g_chi_sq->SetPoint(idx, sh, S2);
514  g_chi_sq_norm->SetPoint(idx, sh, S2_norm);
515  }
516 
517  auto ff_pol2 = std::make_unique<TF1>("ff_pol2", "[0] + [1]*x + [2]*x*x");
518 
519  // determine uncertainty
520  double fit_range = cfg.methOUncFitRange();
521  g_chi_sq->Fit(ff_pol2.get(), "Q", "", sh_best - fit_range, sh_best + fit_range);
522  sh_best_unc = 1. / sqrt(ff_pol2->GetParameter(2));
523 
524  // print results
525  edm::LogInfo("PPSAlignmentHarvester") << std::fixed << std::setprecision(3) << "[x_alignment] "
526  << "sh_best = (" << sh_best << " +- " << sh_best_unc << ") mm";
527 
528  auto g_test_shifted = std::make_unique<TGraphErrors>(*g_test);
529  for (int i = 0; i < g_test_shifted->GetN(); ++i) {
530  g_test_shifted->GetX()[i] += sh_best;
531  }
532 
533  std::unique_ptr<TH1D> histPtr = getTH1DFromTGraphErrors(
534  g_test_shifted.get(), "test_shifted", ";x (mm);S", rpc.x_slice_n_, rpc.x_slice_w_, rpc.x_slice_min_ + sh_best);
535  iBooker.book1DD("h_test_shifted", histPtr.get());
536 
537  if (debug_) {
538  // save graphs
539  g_n_points->Write();
540  g_chi_sq->Write();
541  g_chi_sq_norm->Write();
542  g_test_shifted->SetTitle(";x (mm);S");
543  g_test_shifted->Write("g_test_shifted");
544 
545  // save results
546  auto g_results = std::make_unique<TGraph>();
547  g_results->SetName("g_results");
548  g_results->SetPoint(0, sh_best, sh_best_unc);
549  g_results->SetPoint(1, range_ref.x_min_, range_ref.x_max_);
550  g_results->SetPoint(2, range_test.x_min_, range_test.x_max_);
551  g_results->Write();
552 
553  // save debug canvas
554  auto c_cmp = std::make_unique<TCanvas>("c_cmp");
555  g_ref->SetLineColor(1);
556  g_ref->SetName("g_ref");
557  g_ref->Draw("apl");
558 
559  g_test->SetLineColor(4);
560  g_test->SetName("g_test");
561  g_test->Draw("pl");
562 
563  g_test_shifted->SetLineColor(2);
564  g_test_shifted->SetName("g_test_shifted");
565 
566  g_test_shifted->Draw("pl");
567  c_cmp->Write();
568  }
569 }
570 
571 // method o
573  DQMStore::IGetter& iGetter,
575  const PPSAlignmentConfiguration& cfg_ref) {
576  TDirectory* xAliDir = nullptr;
577  if (debug_)
578  xAliDir = debugFile_->mkdir((std::to_string(seqPos) + ": x alignment").c_str());
579 
580  for (const auto& [sc, sc_ref] : {std::make_pair(cfg.sectorConfig45(), cfg_ref.sectorConfig45()),
581  std::make_pair(cfg.sectorConfig56(), cfg_ref.sectorConfig56())}) {
582  for (const auto& [rpc, rpc_ref] :
583  {std::make_pair(sc.rp_F_, sc_ref.rp_F_), std::make_pair(sc.rp_N_, sc_ref.rp_N_)}) {
584  auto mes_test = iGetter.getAllContents(dqmDir_ + "/worker/" + sc.name_ + "/near_far/x slices, " + rpc.position_);
585  if (mes_test.empty()) {
586  edm::LogWarning("PPSAlignmentHarvester") << "[x_alignment] " << rpc.name_ << ": could not load mes_test";
587  continue;
588  }
589 
590  TDirectory* rpDir = nullptr;
591  if (debug_)
592  rpDir = xAliDir->mkdir(rpc.name_.c_str());
593 
594  auto vec_ref = cfg_ref.matchingReferencePoints().at(rpc.id_);
595  if (vec_ref.empty()) {
596  edm::LogInfo("PPSAlignmentHarvester") << "[x_alignment] " << rpc.name_ << ": reference points vector is empty";
597  continue;
598  }
599 
600  std::unique_ptr<TGraphErrors> g_ref = buildGraphFromVector(vec_ref);
601 
602  if (debug_)
603  gDirectory = rpDir->mkdir("fits_test");
604  std::unique_ptr<TGraphErrors> g_test = buildGraphFromMonitorElements(
605  iGetter, rpc, mes_test, cfg.fitProfileMinBinEntries(), cfg.fitProfileMinNReasonable());
606 
607  // require minimal number of points
608  if (g_ref->GetN() < (int)cfg.methOGraphMinN() || g_test->GetN() < (int)cfg.methOGraphMinN()) {
609  edm::LogWarning("PPSAlignmentHarvester")
610  << "[x_alignment] " << rpc.name_ << ": insufficient data, skipping (g_ref " << g_ref->GetN() << "/"
611  << cfg.methOGraphMinN() << ", g_test " << g_test->GetN() << "/" << cfg.methOGraphMinN() << ")";
612  continue;
613  }
614 
615  iBooker.setCurrentFolder(dqmDir_ + "/harvester/x alignment/" + rpc.name_);
616 
617  std::unique_ptr<TH1D> histPtr = getTH1DFromTGraphErrors(
618  g_ref.get(), "ref", ";x (mm);S", rpc_ref.x_slice_n_, rpc_ref.x_slice_w_, rpc_ref.x_slice_min_);
619  iBooker.book1DD("h_ref", histPtr.get());
620 
621  histPtr =
622  getTH1DFromTGraphErrors(g_test.get(), "test", ";x (mm);S", rpc.x_slice_n_, rpc.x_slice_w_, rpc.x_slice_min_);
623  iBooker.book1DD("h_test", histPtr.get());
624 
625  if (debug_) {
626  gDirectory = rpDir;
627  g_ref->SetTitle(";x (mm);S");
628  g_ref->Write("g_ref");
629  g_test->SetTitle(";x (mm);S");
630  g_test->Write("g_test");
631  }
632 
633  const auto& shiftRange = cfg.matchingShiftRanges().at(rpc.id_);
634  double sh = 0., sh_unc = 0.;
635 
636  // matching
637  doMatch(iBooker,
638  cfg,
639  rpc,
640  g_ref.get(),
641  g_test.get(),
642  cfg_ref.alignment_x_meth_o_ranges().at(rpc.id_),
643  shiftRange.x_min_,
644  shiftRange.x_max_,
645  sh,
646  sh_unc);
647 
648  // save the results
649  CTPPSRPAlignmentCorrectionData rpResult(sh, sh_unc, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
650  xAliResults_.setRPCorrection(rpc.id_, rpResult);
651  edm::LogInfo("PPSAlignmentHarvester") << std::fixed << std::setprecision(3) << "[x_alignment] "
652  << "Setting sh_x of " << rpc.name_ << " to " << sh;
653 
654  // update the shift
655  if (overwriteShX_) {
656  sh_x_map_[rpc.id_] = sh;
657  }
658  }
659  }
660 
661  edm::LogInfo("PPSAlignmentHarvester") << seqPos << ": x_alignment:\n" << xAliResults_;
662 
663  if (textResultsFile_.is_open())
664  textResultsFile_ << seqPos << ": x_alignment:\n" << xAliResults_ << "\n\n";
665 }
666 
667 // -------------------------------- x alignment relative methods --------------------------------
668 
670  DQMStore::IGetter& iGetter,
672  TDirectory* xAliRelDir = nullptr;
673  if (debug_)
674  xAliRelDir = debugFile_->mkdir((std::to_string(seqPos) + ": x_alignment_relative").c_str());
675 
676  auto ff = std::make_unique<TF1>("ff", "[0] + [1]*(x - [2])");
677  auto ff_sl_fix = std::make_unique<TF1>("ff_sl_fix", "[0] + [1]*(x - [2])");
678 
679  // processing
680  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
681  TDirectory* sectorDir = nullptr;
682  if (debug_) {
683  sectorDir = xAliRelDir->mkdir(sc.name_.c_str());
684  gDirectory = sectorDir;
685  }
686 
687  auto* p_x_diffFN_vs_x_N_monitor = iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/near_far/p_x_diffFN_vs_x_N");
688  if (p_x_diffFN_vs_x_N_monitor == nullptr) {
689  edm::LogWarning("PPSAlignmentHarvester")
690  << "[x_alignment_relative] " << sc.name_ << ": cannot load data, skipping";
691  continue;
692  }
693  TProfile* p_x_diffFN_vs_x_N = p_x_diffFN_vs_x_N_monitor->getTProfile();
694 
695  if (p_x_diffFN_vs_x_N->GetEntries() < cfg.nearFarMinEntries()) {
696  edm::LogWarning("PPSAlignmentHarvester")
697  << "[x_alignment_relative] " << sc.name_ << ": insufficient data, skipping (near_far "
698  << p_x_diffFN_vs_x_N->GetEntries() << "/" << cfg.nearFarMinEntries() << ")";
699  continue;
700  }
701 
702  const double x_min = cfg.alignment_x_relative_ranges().at(sc.rp_N_.id_).x_min_;
703  const double x_max = cfg.alignment_x_relative_ranges().at(sc.rp_N_.id_).x_max_;
704 
705  const double sh_x_N = sh_x_map_[sc.rp_N_.id_];
706  double slope = sc.slope_;
707 
708  // calculate the results without slope fixed
709  ff->SetParameters(0., slope, 0.);
710  ff->FixParameter(2, -sh_x_N);
711  ff->SetLineColor(2);
712  p_x_diffFN_vs_x_N->Fit(ff.get(), "Q", "", x_min, x_max);
713 
714  const double a = ff->GetParameter(1), a_unc = ff->GetParError(1);
715  const double b = ff->GetParameter(0), b_unc = ff->GetParError(0);
716 
717  edm::LogInfo("PPSAlignmentHarvester")
718  << "[x_alignment_relative] " << sc.name_ << ":\n"
719  << std::fixed << std::setprecision(3) << " x_min = " << x_min << ", x_max = " << x_max << "\n"
720  << " sh_x_N = " << sh_x_N << ", slope (fix) = " << slope << ", slope (fitted) = " << a;
721 
722  CTPPSRPAlignmentCorrectionData rpResult_N(+b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
723  xAliRelResults_.setRPCorrection(sc.rp_N_.id_, rpResult_N);
724  CTPPSRPAlignmentCorrectionData rpResult_F(-b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
725  xAliRelResults_.setRPCorrection(sc.rp_F_.id_, rpResult_F);
726 
727  // calculate the results with slope fixed
728  ff_sl_fix->SetParameters(0., slope, 0.);
729  ff_sl_fix->FixParameter(1, slope);
730  ff_sl_fix->FixParameter(2, -sh_x_N);
731  ff_sl_fix->SetLineColor(4);
732  p_x_diffFN_vs_x_N->Fit(ff_sl_fix.get(), "Q+", "", x_min, x_max);
733 
734  const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
735 
736  CTPPSRPAlignmentCorrectionData rpResult_sl_fix_N(+b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
737  xAliRelResultsSlopeFixed_.setRPCorrection(sc.rp_N_.id_, rpResult_sl_fix_N);
738  CTPPSRPAlignmentCorrectionData rpResult_sl_fix_F(-b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
739  xAliRelResultsSlopeFixed_.setRPCorrection(sc.rp_F_.id_, rpResult_sl_fix_F);
740 
741  edm::LogInfo("PPSAlignmentHarvester")
742  << "[x_alignment_relative] " << std::fixed << std::setprecision(3) << "ff: " << ff->GetParameter(0) << " + "
743  << ff->GetParameter(1) << " * (x - " << ff->GetParameter(2) << "), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
744  << " + " << ff_sl_fix->GetParameter(1) << " * (x - " << ff_sl_fix->GetParameter(2) << ")";
745 
746  // rebook the diffFN plot in the harvester
747  iBooker.setCurrentFolder(dqmDir_ + "/harvester/x_alignment_relative/" + sc.name_);
748  iBooker.bookProfile("p_x_diffFN_vs_x_N", p_x_diffFN_vs_x_N);
749 
750  if (debug_) {
751  p_x_diffFN_vs_x_N->Write("p_x_diffFN_vs_x_N");
752 
753  auto g_results = std::make_unique<TGraph>();
754  g_results->SetPoint(0, sh_x_N, 0.);
755  g_results->SetPoint(1, a, a_unc);
756  g_results->SetPoint(2, b, b_unc);
757  g_results->SetPoint(3, b_fs, b_fs_unc);
758  g_results->Write("g_results");
759  }
760  }
761 
762  // write results
763  edm::LogInfo("PPSAlignmentHarvester") << seqPos << ": x_alignment_relative:\n"
764  << xAliRelResults_ << seqPos + 1 << ": x_alignment_relative_sl_fix:\n"
766 
767  if (textResultsFile_.is_open()) {
768  textResultsFile_ << seqPos << ": x_alignment_relative:\n" << xAliRelResults_ << "\n";
769  textResultsFile_ << seqPos << ": x_alignment_relative_sl_fix:\n" << xAliRelResultsSlopeFixed_ << "\n\n";
770  }
771 }
772 
773 // -------------------------------- y alignment methods --------------------------------
774 
775 double PPSAlignmentHarvester::findMax(const TF1* ff_fit) {
776  const double mu = ff_fit->GetParameter(1);
777  const double si = ff_fit->GetParameter(2);
778 
779  // unreasonable fit?
780  if (si > 25. || std::fabs(mu) > 100.)
781  return 1E100;
782 
783  double x_max = 1E100;
784  double y_max = -1E100;
785  for (double x = mu - si; x <= mu + si; x += 0.001) {
786  double y = ff_fit->Eval(x);
787  if (y > y_max) {
788  x_max = x;
789  y_max = y;
790  }
791  }
792 
793  return x_max;
794 }
795 
797  const MonitorElement* h2_y_vs_x,
800  TDirectory* d_top = nullptr;
801  if (debug_)
802  d_top = gDirectory;
803 
804  auto ff_fit = std::make_unique<TF1>("ff_fit", "[0] * exp(-(x-[1])*(x-[1])/2./[2]/[2]) + [3] + [4]*x");
805 
806  int h_n = h2_y_vs_x->getNbinsX();
807  double diff = h2_y_vs_x->getTH2D()->GetXaxis()->GetBinWidth(1) / 2.;
808  auto h_mode = iBooker.book1DD("mode",
809  ";x (mm); mode of y (mm)",
810  h_n,
811  h2_y_vs_x->getTH2D()->GetXaxis()->GetBinCenter(1) - diff,
812  h2_y_vs_x->getTH2D()->GetXaxis()->GetBinCenter(h_n) + diff);
813 
814  // find mode for each bin
815  for (int bix = 1; bix <= h_n; bix++) {
816  const double x = h2_y_vs_x->getTH2D()->GetXaxis()->GetBinCenter(bix);
817 
818  char buf[100];
819  sprintf(buf, "h_y_x=%.3f", x);
820  TH1D* h_y = h2_y_vs_x->getTH2D()->ProjectionY(buf, bix, bix);
821 
822  if (h_y->GetEntries() < cfg.multSelProjYMinEntries())
823  continue;
824 
825  if (debug_) {
826  sprintf(buf, "x=%.3f", x);
827  gDirectory = d_top->mkdir(buf);
828  }
829 
830  double conMax = -1.;
831  double conMax_x = 0.;
832  for (int biy = 1; biy < h_y->GetNbinsX(); biy++) {
833  if (h_y->GetBinContent(biy) > conMax) {
834  conMax = h_y->GetBinContent(biy);
835  conMax_x = h_y->GetBinCenter(biy);
836  }
837  }
838 
839  ff_fit->SetParameters(conMax, conMax_x, h_y->GetRMS() * 0.75, 0., 0.);
840  ff_fit->FixParameter(4, 0.);
841 
842  double x_min = rpc.x_min_fit_mode_, x_max = rpc.x_max_fit_mode_;
843  h_y->Fit(ff_fit.get(), "Q", "", x_min, x_max);
844 
845  ff_fit->ReleaseParameter(4);
846  double w = std::min(4., 2. * ff_fit->GetParameter(2));
847  x_min = ff_fit->GetParameter(1) - w;
848  x_max = std::min(rpc.y_max_fit_mode_, ff_fit->GetParameter(1) + w);
849 
850  h_y->Fit(ff_fit.get(), "Q", "", x_min, x_max);
851 
852  if (debug_)
853  h_y->Write("h_y");
854 
855  double y_mode = findMax(ff_fit.get());
856  const double y_mode_fit_unc = ff_fit->GetParameter(2) / 10;
857  const double y_mode_sys_unc = cfg.y_mode_sys_unc();
858  double y_mode_unc = std::sqrt(y_mode_fit_unc * y_mode_fit_unc + y_mode_sys_unc * y_mode_sys_unc);
859 
860  const double chiSqThreshold = cfg.chiSqThreshold();
861 
862  const bool valid =
863  !(std::fabs(y_mode_unc) > cfg.y_mode_unc_max_valid() || std::fabs(y_mode) > cfg.y_mode_max_valid() ||
864  ff_fit->GetChisquare() / ff_fit->GetNDF() > chiSqThreshold);
865 
866  if (debug_) {
867  auto g_data = std::make_unique<TGraph>();
868  g_data->SetPoint(0, y_mode, y_mode_unc);
869  g_data->SetPoint(1, ff_fit->GetChisquare(), ff_fit->GetNDF());
870  g_data->SetPoint(2, valid, 0.);
871  g_data->Write("g_data");
872  }
873 
874  if (!valid)
875  continue;
876 
877  h_mode->Fill(x, y_mode);
878  h_mode->setBinError(bix, y_mode_unc);
879  }
880 
881  return h_mode->getTH1D();
882 }
883 
885  DQMStore::IGetter& iGetter,
887  TDirectory* yAliDir = nullptr;
888  if (debug_)
889  yAliDir = debugFile_->mkdir((std::to_string(seqPos) + ": y_alignment").c_str());
890 
891  auto ff = std::make_unique<TF1>("ff", "[0] + [1]*(x - [2])");
892  auto ff_sl_fix = std::make_unique<TF1>("ff_sl_fix", "[0] + [1]*(x - [2])");
893 
894  // processing
895  for (const auto& sc : {cfg.sectorConfig45(), cfg.sectorConfig56()}) {
896  for (const auto& rpc : {sc.rp_F_, sc.rp_N_}) {
897  TDirectory* rpDir = nullptr;
898  if (debug_) {
899  rpDir = yAliDir->mkdir(rpc.name_.c_str());
900  gDirectory = rpDir->mkdir("x");
901  }
902 
903  auto* h2_y_vs_x =
904  iGetter.get(dqmDir_ + "/worker/" + sc.name_ + "/multiplicity selection/" + rpc.name_ + "/h2_y_vs_x");
905 
906  if (h2_y_vs_x == nullptr) {
907  edm::LogWarning("PPSAlignmentHarvester") << "[y_alignment] " << rpc.name_ << ": cannot load data, skipping";
908  continue;
909  }
910 
911  iBooker.setCurrentFolder(dqmDir_ + "/harvester/y alignment/" + rpc.name_);
912  auto* h_y_cen_vs_x = buildModeGraph(iBooker, h2_y_vs_x, cfg, rpc);
913 
914  if ((unsigned int)h_y_cen_vs_x->GetEntries() < cfg.modeGraphMinN()) {
915  edm::LogWarning("PPSAlignmentHarvester")
916  << "[y_alignment] " << rpc.name_ << ": insufficient data, skipping (mode graph "
917  << h_y_cen_vs_x->GetEntries() << "/" << cfg.modeGraphMinN() << ")";
918  continue;
919  }
920 
921  const double x_min = cfg.alignment_y_ranges().at(rpc.id_).x_min_;
922  const double x_max = cfg.alignment_y_ranges().at(rpc.id_).x_max_;
923 
924  const double sh_x = sh_x_map_[rpc.id_];
925  double slope = rpc.slope_;
926 
927  // calculate the results without slope fixed
928  ff->SetParameters(0., 0., 0.);
929  ff->FixParameter(2, -sh_x);
930  ff->SetLineColor(2);
931  h_y_cen_vs_x->Fit(ff.get(), "Q", "", x_min, x_max);
932 
933  const double a = ff->GetParameter(1), a_unc = ff->GetParError(1);
934  const double b = ff->GetParameter(0), b_unc = ff->GetParError(0);
935 
936  edm::LogInfo("PPSAlignmentHarvester")
937  << "[y_alignment] " << rpc.name_ << ":\n"
938  << std::fixed << std::setprecision(3) << " x_min = " << x_min << ", x_max = " << x_max << "\n"
939  << " sh_x = " << sh_x << ", slope (fix) = " << slope << ", slope (fitted) = " << a;
940 
941  CTPPSRPAlignmentCorrectionData rpResult(0., 0., b, b_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
942  yAliResults_.setRPCorrection(rpc.id_, rpResult);
943 
944  // calculate the results with slope fixed
945  ff_sl_fix->SetParameters(0., 0., 0.);
946  ff_sl_fix->FixParameter(1, slope);
947  ff_sl_fix->FixParameter(2, -sh_x);
948  ff_sl_fix->SetLineColor(4);
949  h_y_cen_vs_x->Fit(ff_sl_fix.get(), "Q+", "", x_min, x_max);
950 
951  const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
952 
953  CTPPSRPAlignmentCorrectionData rpResult_sl_fix(0., 0., b_fs, b_fs_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
954  yAliResultsSlopeFixed_.setRPCorrection(rpc.id_, rpResult_sl_fix);
955 
956  edm::LogInfo("PPSAlignmentHarvester")
957  << "[y_alignment] " << std::fixed << std::setprecision(3) << "ff: " << ff->GetParameter(0) << " + "
958  << ff->GetParameter(1) << " * (x - " << ff->GetParameter(2) << "), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
959  << " + " << ff_sl_fix->GetParameter(1) << " * (x - " << ff_sl_fix->GetParameter(2) << ")";
960 
961  if (debug_) {
962  gDirectory = rpDir;
963 
964  h_y_cen_vs_x->SetTitle(";x (mm); mode of y (mm)");
965  h_y_cen_vs_x->Write("h_y_cen_vs_x");
966 
967  auto g_results = std::make_unique<TGraph>();
968  g_results->SetPoint(0, sh_x, 0.);
969  g_results->SetPoint(1, a, a_unc);
970  g_results->SetPoint(2, b, b_unc);
971  g_results->SetPoint(3, b_fs, b_fs_unc);
972  g_results->Write("g_results");
973  }
974  }
975  }
976 
977  // write results
978  edm::LogInfo("PPSAlignmentHarvester") << seqPos << ": y_alignment:\n"
979  << yAliResults_ << seqPos << ": y_alignment_sl_fix:\n"
981 
982  if (textResultsFile_.is_open()) {
983  textResultsFile_ << seqPos << ": y_alignment:\n" << yAliResults_ << "\n";
984  textResultsFile_ << seqPos << ": y_alignment_sl_fix:\n" << yAliResultsSlopeFixed_ << "\n\n";
985  }
986 }
987 
988 // -------------------------------- other methods --------------------------------
989 
990 // Creates a plot showing a cut applied by the worker. Used only for debug purposes.
992  TH2D* h, const double a, const double c, const double n_si, const double si, const std::string& label) {
993  auto canvas = std::make_unique<TCanvas>();
994  canvas->SetName(label.c_str());
995  canvas->SetLogz(1);
996 
997  h->Draw("colz");
998 
999  double x_min = -30.;
1000  double x_max = 30.;
1001 
1002  auto g_up = std::make_unique<TGraph>();
1003  g_up->SetName("g_up");
1004  g_up->SetPoint(0, x_min, -a * x_min - c + n_si * si);
1005  g_up->SetPoint(1, x_max, -a * x_max - c + n_si * si);
1006  g_up->SetLineColor(1);
1007  g_up->Draw("l");
1008 
1009  auto g_down = std::make_unique<TGraph>();
1010  g_down->SetName("g_down");
1011  g_down->SetPoint(0, x_min, -a * x_min - c - n_si * si);
1012  g_down->SetPoint(1, x_max, -a * x_max - c - n_si * si);
1013  g_down->SetLineColor(1);
1014  g_down->Draw("l");
1015 
1016  canvas->Write();
1017 }
1018 
1019 // Points in TGraph should be sorted (TGraph::Sort())
1020 // if n, binWidth, or min is set to -1, method will find it on its own
1022  TGraphErrors* graph, const std::string& title, const std::string& labels, int n, double binWidth, double min) {
1023  std::unique_ptr<TH1D> hist;
1024  if (n == 0) {
1025  hist = std::make_unique<TH1D>(title.c_str(), labels.c_str(), 0, -10., 10.);
1026  } else if (n == 1) {
1027  hist = std::make_unique<TH1D>(title.c_str(), labels.c_str(), 1, graph->GetPointX(0) - 5., graph->GetPointX(0) + 5.);
1028  } else {
1029  n = n == -1 ? graph->GetN() : n;
1030  binWidth = binWidth == -1 ? graph->GetPointX(1) - graph->GetPointX(0) : binWidth;
1031  double diff = binWidth / 2.;
1032  min = min == -1 ? graph->GetPointX(0) - diff : min;
1033  double max = min + n * binWidth;
1034  hist = std::make_unique<TH1D>(title.c_str(), labels.c_str(), n, min, max);
1035  }
1036 
1037  for (int i = 0; i < graph->GetN(); i++) {
1038  double x, y;
1039  graph->GetPoint(i, x, y);
1040  hist->Fill(x, y);
1041  hist->SetBinError(hist->GetXaxis()->FindBin(x), graph->GetErrorY(i));
1042  }
1043  return hist;
1044 }
1045 
void dqmEndRun(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, edm::Run const &iRun, edm::EventSetup const &iSetup) override
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
int fitProfile(TProfile *p, double x_mean, double x_rms, unsigned int minBinEntries, unsigned int minNBinsReasonable, double &sl, double &sl_unc)
Definition: utils.cc:14
void xAlignment(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg, const PPSAlignmentConfiguration &cfg_ref)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
CTPPSRPAlignmentCorrectionData & getRPCorrection(unsigned int id)
returns the correction value from the RP map
const std::map< unsigned int, SelectionRange > & alignment_x_meth_o_ranges() const
static void writeCutPlot(TH2D *h, const double a, const double c, const double si, const double n_si, const std::string &label)
std::map< unsigned int, double > sh_x_map_
edm::ESGetToken< PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd > esTokenReference_
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
T w() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
CTPPSRPAlignmentCorrectionsData xAliRelResults_
static std::unique_ptr< TH1D > getTH1DFromTGraphErrors(TGraphErrors *graph, const std::string &title="", const std::string &labels="", int n=-1, double binWidth=-1., double min=-1.)
static const double slope[3]
std::string to_string(const V &value)
Definition: OMSAccess.h:71
const std::pair< double, double > yCorrRange_
CTPPSRPAlignmentCorrectionsData yAliResults_
void setRPCorrection(unsigned int id, const CTPPSRPAlignmentCorrectionData &ac)
sets the alignment correction for the given RP
Log< level::Error, false > LogError
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
void xAlignmentRelative(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg)
std::unique_ptr< TGraphErrors > buildGraphFromVector(const std::vector< PPSAlignmentConfiguration::PointErrors > &pv)
char const * label
CTPPSRPAlignmentCorrectionsData yAliResultsSlopeFixed_
MonitorElement * book1DD(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:155
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const SectorConfig & sectorConfig45() const
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
CTPPSRPAlignmentCorrectionsData xAliResults_
PPSAlignmentHarvester(const edm::ParameterSet &iConfig)
T sqrt(T t)
Definition: SSEVec.h:19
virtual std::vector< dqm::harvesting::MonitorElement * > getAllContents(std::string const &path) const
Definition: DQMStore.cc:609
const std::map< unsigned int, std::vector< PointErrors > > & matchingReferencePoints() const
void doMatch(DQMStore::IBooker &iBooker, const PPSAlignmentConfiguration &cfg, const PPSAlignmentConfiguration::RPConfig &rpc, TGraphErrors *g_ref, TGraphErrors *g_test, const PPSAlignmentConfiguration::SelectionRange &range_ref, const double sh_min, const double sh_max, double &sh_best, double &sh_best_unc)
def pv(vc)
Definition: MetAnalyzer.py:7
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
Transition
Definition: Transition.h:12
void yAlignment(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg)
bool getData(T &iHolder) const
Definition: EventSetup.h:122
static double findMax(const TF1 *ff_fit)
const std::vector< std::string > sequence_
edm::ESGetToken< PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd > esTokenTest_
void addRPCorrection(unsigned int, const CTPPSRPAlignmentCorrectionData &, bool sumErrors=true, bool addSh=true, bool addRot=true)
d
Definition: ztail.py:151
std::unique_ptr< TFile > debugFile_
void addCorrections(const CTPPSRPAlignmentCorrectionsData &, bool sumErrors=true, bool addSh=true, bool addRot=true)
adds (merges) corrections on top of the current values
__shared__ Hist hist
Log< level::Info, false > LogInfo
void dqmEndJob(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter) override
std::unique_ptr< TGraphErrors > buildGraphFromMonitorElements(DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration::RPConfig &rpc, const std::vector< MonitorElement *> &mes, const unsigned int fitProfileMinBinEntries, const unsigned int fitProfileMinNReasonable)
double b
Definition: hdecay.h:118
const SectorConfig & sectorConfig56() const
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:673
Container for CTPPS RP alignment corrections. The corrections are stored on two levels - RP and senso...
TH1D * buildModeGraph(DQMStore::IBooker &iBooker, const MonitorElement *h2_y_vs_x, const PPSAlignmentConfiguration &cfg, const PPSAlignmentConfiguration::RPConfig &rpc)
HLT enums.
const std::pair< double, double > xCorrRange_
double a
Definition: hdecay.h:119
CTPPSRPAlignmentCorrectionsData xAliRelResultsSlopeFixed_
def canvas(sub, attr)
Definition: svgfig.py:482
virtual int getNbinsX() const
get # of bins in X-axis
bool isAvailable() const
Definition: Service.h:40
Log< level::Warning, false > LogWarning
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
Alignment correction for an element of the CT-PPS detector. Within the geometry description, every sensor (more generally every element) is given its translation and rotation. These two quantities shall be understood in local-to-global coordinate transform. That is, if r_l is a point in local coordinate system and x_g in global, then it holds.
Definition: Run.h:45
virtual TH2D * getTH2D() const