43 #include "TGraphErrors.h" 68 std::unique_ptr<TGraphErrors>
buildGraphFromVector(
const std::vector<PPSAlignmentConfiguration::PointErrors>&
pv);
71 const std::vector<MonitorElement*>& mes,
72 const unsigned int fitProfileMinBinEntries,
73 const unsigned int fitProfileMinNReasonable);
96 static double findMax(
const TF1* ff_fit);
106 TH2D*
h,
const double a,
const double c,
const double si,
const double n_si,
const std::string&
label);
111 double binWidth = -1.,
153 dqmDir_(iConfig.getParameter<
std::
string>(
"dqm_dir")),
155 overwriteShX_(iConfig.getParameter<
bool>(
"overwrite_sh_x")),
156 writeSQLiteResults_(iConfig.getParameter<
bool>(
"write_sqlite_results")),
157 xAliRelFinalSlopeFixed_(iConfig.getParameter<
bool>(
"x_ali_rel_final_slope_fixed")),
158 yAliFinalSlopeFixed_(iConfig.getParameter<
bool>(
"y_ali_final_slope_fixed")),
159 xCorrRange_(
std::make_pair(iConfig.getParameter<double>(
"x_corr_min") / 1000.,
160 iConfig.getParameter<double>(
"x_corr_max") / 1000.)),
161 yCorrRange_(
std::make_pair(iConfig.getParameter<double>(
"y_corr_min") / 1000.,
162 iConfig.getParameter<double>(
"y_corr_max") / 1000.)),
163 detectorId_(iConfig.getParameter<unsigned
int>(
"detector_id")),
164 subdetectorId_(iConfig.getParameter<unsigned
int>(
"subdetector_id")),
165 debug_(iConfig.getParameter<
bool>(
"debug")) {
167 if (!textResultsPath.empty()) {
171 debugFile_ = std::make_unique<TFile>(
"debug_harvester.root",
"recreate");
174 edm::LogInfo(
"PPSAlignmentHarvester").log([&](
auto& li) {
175 li <<
"parameters:\n";
176 li <<
"* dqm_dir: " <<
dqmDir_ <<
"\n";
177 li <<
"* sequence:\n";
179 li <<
" " <<
i + 1 <<
": " <<
sequence_[
i] <<
"\n";
181 li <<
"* overwrite_sh_x: " << std::boolalpha <<
overwriteShX_ <<
"\n";
182 li <<
"* text_results_path: " << textResultsPath <<
"\n";
194 li <<
"* debug: " << std::boolalpha <<
debug_;
208 desc.add<std::vector<std::string>>(
"sequence", {
"x_alignment",
"x_alignment_relative",
"y_alignment"});
209 desc.add<
bool>(
"overwrite_sh_x",
true);
211 desc.add<
bool>(
"write_sqlite_results",
false);
212 desc.add<
bool>(
"x_ali_rel_final_slope_fixed",
false);
213 desc.add<
bool>(
"y_ali_final_slope_fixed",
false);
214 desc.add<
double>(
"x_corr_min", -1
'000'000.);
215 desc.add<
double>(
"x_corr_max", 1
'000'000.);
216 desc.add<
double>(
"y_corr_min", -1
'000'000.);
217 desc.add<
double>(
"y_corr_max", 1
'000'000.);
218 desc.add<
unsigned int>(
"detector_id", 7);
219 desc.add<
unsigned int>(
"subdetector_id", 4);
220 desc.add<
bool>(
"debug",
false);
236 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
237 for (
const auto&
rpc : {sc.rp_N_, sc.rp_F_}) {
241 edm::LogInfo(
"PPSAlignmentHarvester").log([&](
auto& li) {
242 li <<
"Setting sh_x from config of:\n";
243 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
244 for (
const auto&
rpc : {sc.rp_N_, sc.rp_F_}) {
245 li <<
" " <<
rpc.name_ <<
" to " <<
std::fixed << std::setprecision(3) <<
rpc.sh_x_;
246 if (
rpc.name_ !=
"R_2_F")
252 bool doXAli =
false, doXAliRel =
false, doYAli =
false;
254 if (aliMethod ==
"x_alignment") {
257 }
else if (aliMethod ==
"x_alignment_relative") {
260 }
else if (aliMethod ==
"y_alignment") {
264 edm::LogError(
"PPSAlignmentHarvester") << aliMethod <<
" is a wrong method name.";
273 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
278 double d_x_rel_N, d_x_rel_F;
288 double b = d_x_rel_N - d_x_rel_F;
289 double xCorrRel =
b + d_x_F - d_x_N;
291 CTPPSRPAlignmentCorrectionData corrRelN(xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
293 CTPPSRPAlignmentCorrectionData corrRelF(-xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
307 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
308 for (
const auto&
rpc : {sc.rp_F_, sc.rp_N_}) {
313 <<
"The horizontal shift of " <<
rpc.name_ <<
" (" <<
std::fixed << std::setw(9) << std::setprecision(1)
314 << rpResults.getShX() * 1000. <<
" um) outside of the reasonability range. Setting it to 0.";
315 rpResults.setShX(0.);
316 rpResults.setShXUnc(0.);
321 <<
"The vertical shift of " <<
rpc.name_ <<
" (" <<
std::fixed << std::setw(9) << std::setprecision(1)
322 << rpResults.getShY() * 1000. <<
" um) outside of the reasonability range. Setting it to 0.";
323 rpResults.setShY(0.);
324 rpResults.setShYUnc(0.);
330 edm::LogInfo(
"PPSAlignmentHarvester") <<
"final merged results:\n" << finalResults;
339 edm::LogInfo(
"PPSAlignmentHarvester") <<
"trying to store final merged results with long ids:\n" 340 << longIdFinalResults;
345 longIdFinalResults, poolDbService->
currentTime(),
"CTPPSRPAlignmentCorrectionsDataRcd");
348 <<
"Could not store the results in a DB object. PoolDBService not available.";
354 TDirectory* cutsDir =
debugFile_->mkdir(
"cuts");
355 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
356 TDirectory* sectorDir = cutsDir->mkdir(sc.name_.c_str());
358 gDirectory = sectorDir->mkdir(
"cut_h");
359 auto* h2_cut_h_bef_monitor = iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/cuts/cut_h/h2_cut_h_bef");
360 auto* h2_cut_h_aft_monitor = iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/cuts/cut_h/h2_cut_h_aft");
362 h2_cut_h_bef_monitor->getTH2D(), sc.cut_h_a_, sc.cut_h_c_,
cfg.n_si(), sc.cut_h_si_,
"canvas_before");
363 writeCutPlot(h2_cut_h_aft_monitor->getTH2D(), sc.cut_h_a_, sc.cut_h_c_,
cfg.n_si(), sc.cut_h_si_,
"canvas_after");
365 gDirectory = sectorDir->mkdir(
"cut_v");
366 auto* h2_cut_v_bef_monitor = iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/cuts/cut_v/h2_cut_v_bef");
367 auto* h2_cut_v_aft_monitor = iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/cuts/cut_v/h2_cut_v_aft");
369 h2_cut_v_bef_monitor->getTH2D(), sc.cut_v_a_, sc.cut_v_c_,
cfg.n_si(), sc.cut_v_si_,
"canvas_before");
370 writeCutPlot(h2_cut_v_aft_monitor->getTH2D(), sc.cut_v_a_, sc.cut_v_c_,
cfg.n_si(), sc.cut_v_si_,
"canvas_after");
379 const std::vector<PPSAlignmentConfiguration::PointErrors>&
pv) {
380 auto g = std::make_unique<TGraphErrors>();
382 for (
unsigned int i = 0;
i <
pv.size();
i++) {
383 const auto&
p =
pv[
i];
384 g->SetPoint(
i,
p.x_,
p.y_);
385 g->SetPointError(
i,
p.ex_,
p.ey_);
396 const std::vector<MonitorElement*>& mes,
397 const unsigned int fitProfileMinBinEntries,
398 const unsigned int fitProfileMinNReasonable) {
399 auto g = std::make_unique<TGraphErrors>();
401 for (
auto*
me : mes) {
402 if (
me->getName() ==
"h_y")
406 size_t parentPos = parentPath.substr(0, parentPath.size() - 1).find_last_of(
'/') + 1;
407 std::string parentName = parentPath.substr(parentPos);
408 std::replace(parentName.begin(), parentName.end(),
'_',
'.');
409 size_t d = parentName.find(
'-');
410 const double x_min = std::stod(parentName.substr(0,
d));
411 const double x_max = std::stod(parentName.substr(
d + 1));
413 TH1D* h_y =
me->getTH1D();
416 auto* p_y_diffFN_vs_y_monitor = iGetter.
get(parentPath +
"p_y_diffFN_vs_y");
417 if (p_y_diffFN_vs_y_monitor ==
nullptr) {
418 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[x_alignment] could not find p_y_diffFN_vs_y in: " << parentPath;
421 TProfile* p_y_diffFN_vs_y = p_y_diffFN_vs_y_monitor->getTProfile();
423 double y_cen = h_y->GetMean() +
rpc.y_cen_add_;
424 double y_width = h_y->GetRMS() *
rpc.y_width_mult_;
428 p_y_diffFN_vs_y, y_cen, y_width, fitProfileMinBinEntries, fitProfileMinNReasonable, sl, sl_unc);
433 p_y_diffFN_vs_y->Write(parentName.c_str());
436 g->SetPoint(
idx, (x_max + x_min) / 2., sl);
437 g->SetPointError(
idx, (x_max - x_min) / 2., sl_unc);
450 TGraphErrors* g_test,
455 double& sh_best_unc) {
456 const auto range_test =
cfg.alignment_x_meth_o_ranges().at(
rpc.id_);
460 <<
"ref: x_min = " << range_ref.
x_min_ <<
", x_max = " << range_ref.
x_max_ 462 <<
"test: x_min = " << range_test.x_min_ <<
", x_max = " << range_test.x_max_;
465 auto s_ref = std::make_unique<TSpline3>(
"s_ref", g_ref->GetX(), g_ref->GetY(), g_ref->GetN());
468 auto g_n_points = std::make_unique<TGraph>();
469 g_n_points->SetName(
"g_n_points");
470 g_n_points->SetTitle(
";sh;N");
471 auto g_chi_sq = std::make_unique<TGraph>();
472 g_chi_sq->SetName(
"g_chi_sq");
473 g_chi_sq->SetTitle(
";sh;S2");
474 auto g_chi_sq_norm = std::make_unique<TGraph>();
475 g_chi_sq_norm->SetName(
"g_chi_sq_norm");
476 g_chi_sq_norm->SetTitle(
";sh;S2 / N");
479 double S2_norm_best = 1E100;
481 for (
double sh = sh_min; sh <= sh_max; sh +=
cfg.x_ali_sh_step()) {
486 for (
int i = 0;
i < g_test->GetN(); ++
i) {
487 const double x_test = g_test->GetX()[
i];
488 const double y_test = g_test->GetY()[
i];
489 const double y_test_unc = g_test->GetErrorY(
i);
491 const double x_ref = x_test + sh;
493 if (x_ref < range_ref.x_min_ || x_ref > range_ref.
x_max_ || x_test < range_test.x_min_ ||
494 x_test > range_test.x_max_)
497 const double y_ref = s_ref->Eval(x_ref);
499 int js = -1, jg = -1;
500 double xs = -1E100, xg = +1E100;
501 for (
int j = 0;
j < g_ref->GetN(); ++
j) {
502 const double x = g_ref->GetX()[
j];
503 if (x < x_ref && x > xs) {
507 if (
x > x_ref &&
x < xg) {
515 const double y_ref_unc = (g_ref->GetErrorY(js) + g_ref->GetErrorY(jg)) / 2.;
518 const double S2_inc =
pow(y_test - y_ref, 2.) / (y_ref_unc * y_ref_unc + y_test_unc * y_test_unc);
523 double S2_norm = S2 / n_points;
525 if (S2_norm < S2_norm_best) {
526 S2_norm_best = S2_norm;
531 int idx = g_n_points->GetN();
532 g_n_points->SetPoint(
idx, sh, n_points);
533 g_chi_sq->SetPoint(
idx, sh, S2);
534 g_chi_sq_norm->SetPoint(
idx, sh, S2_norm);
537 auto ff_pol2 = std::make_unique<TF1>(
"ff_pol2",
"[0] + [1]*x + [2]*x*x");
540 double fit_range =
cfg.methOUncFitRange();
541 g_chi_sq->Fit(ff_pol2.get(),
"Q",
"", sh_best - fit_range, sh_best + fit_range);
542 sh_best_unc = 1. /
sqrt(ff_pol2->GetParameter(2));
546 <<
"sh_best = (" << sh_best <<
" +- " << sh_best_unc <<
") mm";
548 auto g_test_shifted = std::make_unique<TGraphErrors>(*g_test);
549 for (
int i = 0;
i < g_test_shifted->GetN(); ++
i) {
550 g_test_shifted->GetX()[
i] += sh_best;
554 g_test_shifted.get(),
"test_shifted",
";x (mm);S",
rpc.x_slice_n_,
rpc.x_slice_w_,
rpc.x_slice_min_ + sh_best);
555 iBooker.
book1DD(
"h_test_shifted", histPtr.get());
561 g_chi_sq_norm->Write();
562 g_test_shifted->SetTitle(
";x (mm);S");
563 g_test_shifted->Write(
"g_test_shifted");
566 auto g_results = std::make_unique<TGraph>();
567 g_results->SetName(
"g_results");
568 g_results->SetPoint(0, sh_best, sh_best_unc);
569 g_results->SetPoint(1, range_ref.
x_min_, range_ref.
x_max_);
570 g_results->SetPoint(2, range_test.x_min_, range_test.x_max_);
574 auto c_cmp = std::make_unique<TCanvas>(
"c_cmp");
575 g_ref->SetLineColor(1);
576 g_ref->SetName(
"g_ref");
579 g_test->SetLineColor(4);
580 g_test->SetName(
"g_test");
583 g_test_shifted->SetLineColor(2);
584 g_test_shifted->SetName(
"g_test_shifted");
586 g_test_shifted->Draw(
"pl");
596 TDirectory* xAliDir =
nullptr;
600 for (
const auto& [sc, sc_ref] : {std::make_pair(
cfg.sectorConfig45(), cfg_ref.
sectorConfig45()),
602 for (
const auto& [
rpc, rpc_ref] :
603 {std::make_pair(sc.rp_F_, sc_ref.rp_F_), std::make_pair(sc.rp_N_, sc_ref.rp_N_)}) {
605 if (mes_test.empty()) {
606 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[x_alignment] " <<
rpc.name_ <<
": could not load mes_test";
610 TDirectory* rpDir =
nullptr;
612 rpDir = xAliDir->mkdir(
rpc.name_.c_str());
615 if (vec_ref.empty()) {
616 edm::LogInfo(
"PPSAlignmentHarvester") <<
"[x_alignment] " <<
rpc.name_ <<
": reference points vector is empty";
623 gDirectory = rpDir->mkdir(
"fits_test");
625 iGetter,
rpc, mes_test,
cfg.fitProfileMinBinEntries(),
cfg.fitProfileMinNReasonable());
628 if (g_ref->GetN() < (
int)
cfg.methOGraphMinN() || g_test->GetN() < (
int)
cfg.methOGraphMinN()) {
630 <<
"[x_alignment] " <<
rpc.name_ <<
": insufficient data, skipping (g_ref " << g_ref->GetN() <<
"/" 631 <<
cfg.methOGraphMinN() <<
", g_test " << g_test->GetN() <<
"/" <<
cfg.methOGraphMinN() <<
")";
638 g_ref.get(),
"ref",
";x (mm);S", rpc_ref.x_slice_n_, rpc_ref.x_slice_w_, rpc_ref.x_slice_min_);
639 iBooker.
book1DD(
"h_ref", histPtr.get());
643 iBooker.
book1DD(
"h_test", histPtr.get());
647 g_ref->SetTitle(
";x (mm);S");
648 g_ref->Write(
"g_ref");
649 g_test->SetTitle(
";x (mm);S");
650 g_test->Write(
"g_test");
653 const auto& shiftRange =
cfg.matchingShiftRanges().at(
rpc.id_);
654 double sh = 0., sh_unc = 0.;
669 CTPPSRPAlignmentCorrectionData rpResult(sh, sh_unc, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
672 <<
"Setting sh_x of " <<
rpc.name_ <<
" to " << sh;
692 TDirectory* xAliRelDir =
nullptr;
696 auto ff = std::make_unique<TF1>(
"ff",
"[0] + [1]*(x - [2])");
697 auto ff_sl_fix = std::make_unique<TF1>(
"ff_sl_fix",
"[0] + [1]*(x - [2])");
700 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
701 TDirectory* sectorDir =
nullptr;
703 sectorDir = xAliRelDir->mkdir(sc.name_.c_str());
704 gDirectory = sectorDir;
707 auto* p_x_diffFN_vs_x_N_monitor = iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/near_far/p_x_diffFN_vs_x_N");
708 if (p_x_diffFN_vs_x_N_monitor ==
nullptr) {
710 <<
"[x_alignment_relative] " << sc.name_ <<
": cannot load data, skipping";
713 TProfile* p_x_diffFN_vs_x_N = p_x_diffFN_vs_x_N_monitor->getTProfile();
715 if (p_x_diffFN_vs_x_N->GetEntries() <
cfg.nearFarMinEntries()) {
717 <<
"[x_alignment_relative] " << sc.name_ <<
": insufficient data, skipping (near_far " 718 << p_x_diffFN_vs_x_N->GetEntries() <<
"/" <<
cfg.nearFarMinEntries() <<
")";
722 const double x_min =
cfg.alignment_x_relative_ranges().at(sc.rp_N_.id_).x_min_;
723 const double x_max =
cfg.alignment_x_relative_ranges().at(sc.rp_N_.id_).x_max_;
725 const double sh_x_N =
sh_x_map_[sc.rp_N_.id_];
726 double slope = sc.slope_;
729 ff->SetParameters(0.,
slope, 0.);
730 ff->FixParameter(2, -sh_x_N);
732 p_x_diffFN_vs_x_N->Fit(
ff.get(),
"Q",
"", x_min, x_max);
734 const double a =
ff->GetParameter(1), a_unc =
ff->GetParError(1);
735 const double b =
ff->GetParameter(0), b_unc =
ff->GetParError(0);
738 <<
"[x_alignment_relative] " << sc.name_ <<
":\n" 739 <<
std::fixed << std::setprecision(3) <<
" x_min = " << x_min <<
", x_max = " << x_max <<
"\n" 740 <<
" sh_x_N = " << sh_x_N <<
", slope (fix) = " <<
slope <<
", slope (fitted) = " <<
a;
743 CTPPSRPAlignmentCorrectionData rpResult_N(+
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
745 CTPPSRPAlignmentCorrectionData rpResult_F(-
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
749 ff_sl_fix->SetParameters(0.,
slope, 0.);
750 ff_sl_fix->FixParameter(1,
slope);
751 ff_sl_fix->FixParameter(2, -sh_x_N);
752 ff_sl_fix->SetLineColor(4);
753 p_x_diffFN_vs_x_N->Fit(ff_sl_fix.get(),
"Q+",
"", x_min, x_max);
755 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
758 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_N(+b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
760 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_F(-b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
764 <<
"[x_alignment_relative] " <<
std::fixed << std::setprecision(3) <<
"ff: " <<
ff->GetParameter(0) <<
" + " 765 <<
ff->GetParameter(1) <<
" * (x - " <<
ff->GetParameter(2) <<
"), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
766 <<
" + " << ff_sl_fix->GetParameter(1) <<
" * (x - " << ff_sl_fix->GetParameter(2) <<
")";
770 iBooker.
bookProfile(
"p_x_diffFN_vs_x_N", p_x_diffFN_vs_x_N);
773 p_x_diffFN_vs_x_N->Write(
"p_x_diffFN_vs_x_N");
775 auto g_results = std::make_unique<TGraph>();
776 g_results->SetPoint(0, sh_x_N, 0.);
777 g_results->SetPoint(1,
a, a_unc);
778 g_results->SetPoint(2,
b, b_unc);
779 g_results->SetPoint(3, b_fs, b_fs_unc);
780 g_results->Write(
"g_results");
798 const double mu = ff_fit->GetParameter(1);
799 const double si = ff_fit->GetParameter(2);
802 if (si > 25. || std::fabs(
mu) > 100.)
805 double x_max = 1E100;
806 double y_max = -1E100;
807 for (
double x =
mu - si;
x <=
mu + si;
x += 0.001) {
808 double y = ff_fit->Eval(
x);
822 TDirectory* d_top =
nullptr;
826 auto ff_fit = std::make_unique<TF1>(
"ff_fit",
"[0] * exp(-(x-[1])*(x-[1])/2./[2]/[2]) + [3] + [4]*x");
829 double diff = h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinWidth(1) / 2.;
830 auto h_mode = iBooker.
book1DD(
"mode",
831 ";x (mm); mode of y (mm)",
833 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(1) -
diff,
834 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(h_n) +
diff);
837 for (
int bix = 1; bix <= h_n; bix++) {
838 const double x = h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(bix);
841 sprintf(
buf,
"h_y_x=%.3f",
x);
842 TH1D* h_y = h2_y_vs_x->
getTH2D()->ProjectionY(
buf, bix, bix);
844 if (h_y->GetEntries() <
cfg.multSelProjYMinEntries())
848 sprintf(
buf,
"x=%.3f",
x);
849 gDirectory = d_top->mkdir(
buf);
853 double conMax_x = 0.;
854 for (
int biy = 1; biy < h_y->GetNbinsX(); biy++) {
855 if (h_y->GetBinContent(biy) > conMax) {
856 conMax = h_y->GetBinContent(biy);
857 conMax_x = h_y->GetBinCenter(biy);
861 ff_fit->SetParameters(conMax, conMax_x, h_y->GetRMS() * 0.75, 0., 0.);
862 ff_fit->FixParameter(4, 0.);
864 double x_min =
rpc.x_min_fit_mode_, x_max =
rpc.x_max_fit_mode_;
865 h_y->Fit(ff_fit.get(),
"Q",
"", x_min, x_max);
867 ff_fit->ReleaseParameter(4);
868 double w =
std::min(4., 2. * ff_fit->GetParameter(2));
869 x_min = ff_fit->GetParameter(1) -
w;
870 x_max =
std::min(
rpc.y_max_fit_mode_, ff_fit->GetParameter(1) +
w);
872 h_y->Fit(ff_fit.get(),
"Q",
"", x_min, x_max);
877 double y_mode =
findMax(ff_fit.get());
878 const double y_mode_fit_unc = ff_fit->GetParameter(2) / 10;
879 const double y_mode_sys_unc =
cfg.y_mode_sys_unc();
880 double y_mode_unc =
std::sqrt(y_mode_fit_unc * y_mode_fit_unc + y_mode_sys_unc * y_mode_sys_unc);
882 const double chiSqThreshold =
cfg.chiSqThreshold();
885 !(std::fabs(y_mode_unc) >
cfg.y_mode_unc_max_valid() || std::fabs(y_mode) >
cfg.y_mode_max_valid() ||
886 ff_fit->GetChisquare() / ff_fit->GetNDF() > chiSqThreshold);
889 auto g_data = std::make_unique<TGraph>();
890 g_data->SetPoint(0, y_mode, y_mode_unc);
891 g_data->SetPoint(1, ff_fit->GetChisquare(), ff_fit->GetNDF());
892 g_data->SetPoint(2,
valid, 0.);
893 g_data->Write(
"g_data");
899 h_mode->Fill(
x, y_mode);
900 h_mode->setBinError(bix, y_mode_unc);
903 return h_mode->getTH1D();
909 TDirectory* yAliDir =
nullptr;
913 auto ff = std::make_unique<TF1>(
"ff",
"[0] + [1]*(x - [2])");
914 auto ff_sl_fix = std::make_unique<TF1>(
"ff_sl_fix",
"[0] + [1]*(x - [2])");
917 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
918 for (
const auto&
rpc : {sc.rp_F_, sc.rp_N_}) {
919 TDirectory* rpDir =
nullptr;
921 rpDir = yAliDir->mkdir(
rpc.name_.c_str());
922 gDirectory = rpDir->mkdir(
"x");
926 iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/multiplicity selection/" +
rpc.name_ +
"/h2_y_vs_x");
928 if (h2_y_vs_x ==
nullptr) {
929 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[y_alignment] " <<
rpc.name_ <<
": cannot load data, skipping";
936 if ((
unsigned int)h_y_cen_vs_x->GetEntries() <
cfg.modeGraphMinN()) {
938 <<
"[y_alignment] " <<
rpc.name_ <<
": insufficient data, skipping (mode graph " 939 << h_y_cen_vs_x->GetEntries() <<
"/" <<
cfg.modeGraphMinN() <<
")";
943 const double x_min =
cfg.alignment_y_ranges().at(
rpc.id_).x_min_;
944 const double x_max =
cfg.alignment_y_ranges().at(
rpc.id_).x_max_;
950 ff->SetParameters(0., 0., 0.);
951 ff->FixParameter(2, -sh_x);
953 h_y_cen_vs_x->Fit(
ff.get(),
"Q",
"", x_min, x_max);
955 const double a =
ff->GetParameter(1), a_unc =
ff->GetParError(1);
956 const double b =
ff->GetParameter(0), b_unc =
ff->GetParError(0);
959 <<
"[y_alignment] " <<
rpc.name_ <<
":\n" 960 <<
std::fixed << std::setprecision(3) <<
" x_min = " << x_min <<
", x_max = " << x_max <<
"\n" 961 <<
" sh_x = " << sh_x <<
", slope (fix) = " <<
slope <<
", slope (fitted) = " <<
a;
964 CTPPSRPAlignmentCorrectionData rpResult(0., 0., -
b, b_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
968 ff_sl_fix->SetParameters(0., 0., 0.);
969 ff_sl_fix->FixParameter(1,
slope);
970 ff_sl_fix->FixParameter(2, -sh_x);
971 ff_sl_fix->SetLineColor(4);
972 h_y_cen_vs_x->Fit(ff_sl_fix.get(),
"Q+",
"", x_min, x_max);
974 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
976 CTPPSRPAlignmentCorrectionData rpResult_sl_fix(0., 0., -b_fs, b_fs_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
980 <<
"[y_alignment] " <<
std::fixed << std::setprecision(3) <<
"ff: " <<
ff->GetParameter(0) <<
" + " 981 <<
ff->GetParameter(1) <<
" * (x - " <<
ff->GetParameter(2) <<
"), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
982 <<
" + " << ff_sl_fix->GetParameter(1) <<
" * (x - " << ff_sl_fix->GetParameter(2) <<
")";
987 h_y_cen_vs_x->SetTitle(
";x (mm); mode of y (mm)");
988 h_y_cen_vs_x->Write(
"h_y_cen_vs_x");
990 auto g_results = std::make_unique<TGraph>();
991 g_results->SetPoint(0, sh_x, 0.);
992 g_results->SetPoint(1,
a, a_unc);
993 g_results->SetPoint(2, -
b, b_unc);
994 g_results->SetPoint(3, -b_fs, b_fs_unc);
995 g_results->Write(
"g_results");
1015 TH2D*
h,
const double a,
const double c,
const double n_si,
const double si,
const std::string&
label) {
1016 auto canvas = std::make_unique<TCanvas>();
1022 double x_min = -30.;
1025 auto g_up = std::make_unique<TGraph>();
1026 g_up->SetName(
"g_up");
1027 g_up->SetPoint(0, x_min, -
a * x_min -
c + n_si * si);
1028 g_up->SetPoint(1, x_max, -
a * x_max -
c + n_si * si);
1029 g_up->SetLineColor(1);
1032 auto g_down = std::make_unique<TGraph>();
1033 g_down->SetName(
"g_down");
1034 g_down->SetPoint(0, x_min, -
a * x_min -
c - n_si * si);
1035 g_down->SetPoint(1, x_max, -
a * x_max -
c - n_si * si);
1036 g_down->SetLineColor(1);
1046 std::unique_ptr<TH1D>
hist;
1048 hist = std::make_unique<TH1D>(
title.c_str(),
labels.c_str(), 0, -10., 10.);
1049 }
else if (
n == 1) {
1050 hist = std::make_unique<TH1D>(
title.c_str(),
labels.c_str(), 1, graph->GetPointX(0) - 5., graph->GetPointX(0) + 5.);
1052 n =
n == -1 ? graph->GetN() :
n;
1053 binWidth = binWidth == -1 ? graph->GetPointX(1) - graph->GetPointX(0) : binWidth;
1054 double diff = binWidth / 2.;
1056 double max =
min +
n * binWidth;
1060 for (
int i = 0;
i < graph->GetN();
i++) {
1062 graph->GetPoint(
i,
x,
y);
1064 hist->SetBinError(
hist->GetXaxis()->FindBin(
x), graph->GetErrorY(
i));
1073 unsigned int arm = shortId / 100;
1074 unsigned int station = (shortId / 10) % 10;
1075 unsigned int rp = shortId % 10;
1082 return longIdResults;
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)
void xAlignment(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg, const PPSAlignmentConfiguration &cfg_ref)
T getParameter(std::string const &) const
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)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
std::map< unsigned int, double > sh_x_map_
CTPPSRPAlignmentCorrectionsData getLongIdResults(CTPPSRPAlignmentCorrectionsData finalResults)
edm::ESGetToken< PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd > esTokenReference_
virtual void setCurrentFolder(std::string const &fullpath)
std::ofstream textResultsFile_
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]
def replace(string, replacements)
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
const mapType & getRPMap() const
returns the map of RP alignment corrections
static std::string to_string(const XMLCh *ch)
void xAlignmentRelative(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg)
std::unique_ptr< TGraphErrors > buildGraphFromVector(const std::vector< PPSAlignmentConfiguration::PointErrors > &pv)
CTPPSRPAlignmentCorrectionsData yAliResultsSlopeFixed_
MonitorElement * book1DD(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
cond::Time_t currentTime() const
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())
CTPPSRPAlignmentCorrectionsData xAliResults_
const bool writeSQLiteResults_
PPSAlignmentHarvester(const edm::ParameterSet &iConfig)
~PPSAlignmentHarvester() override
const bool xAliRelFinalSlopeFixed_
virtual std::vector< dqm::harvesting::MonitorElement * > getAllContents(std::string const &path) const
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)
const bool yAliFinalSlopeFixed_
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
void yAlignment(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, const PPSAlignmentConfiguration &cfg)
#define DEFINE_FWK_MODULE(type)
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)
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
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)
const SectorConfig & sectorConfig56() const
virtual MonitorElement * get(std::string const &fullpath) const
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)
const std::pair< double, double > xCorrRange_
const std::string dqmDir_
CTPPSRPAlignmentCorrectionsData xAliRelResultsSlopeFixed_
virtual int getNbinsX() const
get # of bins in X-axis
Log< level::Warning, false > LogWarning
const unsigned int detectorId_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Power< A, B >::type pow(const A &a, const B &b)
const unsigned int subdetectorId_
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.
virtual TH2D * getTH2D() const