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",
true);
213 desc.add<
bool>(
"y_ali_final_slope_fixed",
true);
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;
742 CTPPSRPAlignmentCorrectionData rpResult_N(+
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
744 CTPPSRPAlignmentCorrectionData rpResult_F(-
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
748 ff_sl_fix->SetParameters(0.,
slope, 0.);
749 ff_sl_fix->FixParameter(1,
slope);
750 ff_sl_fix->FixParameter(2, -sh_x_N);
751 ff_sl_fix->SetLineColor(4);
752 p_x_diffFN_vs_x_N->Fit(ff_sl_fix.get(),
"Q+",
"", x_min, x_max);
754 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
756 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_N(+b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
758 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_F(-b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
762 <<
"[x_alignment_relative] " <<
std::fixed << std::setprecision(3) <<
"ff: " <<
ff->GetParameter(0) <<
" + " 763 <<
ff->GetParameter(1) <<
" * (x - " <<
ff->GetParameter(2) <<
"), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
764 <<
" + " << ff_sl_fix->GetParameter(1) <<
" * (x - " << ff_sl_fix->GetParameter(2) <<
")";
768 iBooker.
bookProfile(
"p_x_diffFN_vs_x_N", p_x_diffFN_vs_x_N);
771 p_x_diffFN_vs_x_N->Write(
"p_x_diffFN_vs_x_N");
773 auto g_results = std::make_unique<TGraph>();
774 g_results->SetPoint(0, sh_x_N, 0.);
775 g_results->SetPoint(1,
a, a_unc);
776 g_results->SetPoint(2,
b, b_unc);
777 g_results->SetPoint(3, b_fs, b_fs_unc);
778 g_results->Write(
"g_results");
796 const double mu = ff_fit->GetParameter(1);
797 const double si = ff_fit->GetParameter(2);
800 if (si > 25. || std::fabs(
mu) > 100.)
803 double x_max = 1E100;
804 double y_max = -1E100;
805 for (
double x =
mu - si;
x <=
mu + si;
x += 0.001) {
806 double y = ff_fit->Eval(
x);
820 TDirectory* d_top =
nullptr;
824 auto ff_fit = std::make_unique<TF1>(
"ff_fit",
"[0] * exp(-(x-[1])*(x-[1])/2./[2]/[2]) + [3] + [4]*x");
827 double diff = h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinWidth(1) / 2.;
828 auto h_mode = iBooker.
book1DD(
"mode",
829 ";x (mm); mode of y (mm)",
831 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(1) -
diff,
832 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(h_n) +
diff);
835 for (
int bix = 1; bix <= h_n; bix++) {
836 const double x = h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(bix);
839 sprintf(
buf,
"h_y_x=%.3f",
x);
840 TH1D* h_y = h2_y_vs_x->
getTH2D()->ProjectionY(
buf, bix, bix);
842 if (h_y->GetEntries() <
cfg.multSelProjYMinEntries())
846 sprintf(
buf,
"x=%.3f",
x);
847 gDirectory = d_top->mkdir(
buf);
851 double conMax_x = 0.;
852 for (
int biy = 1; biy < h_y->GetNbinsX(); biy++) {
853 if (h_y->GetBinContent(biy) > conMax) {
854 conMax = h_y->GetBinContent(biy);
855 conMax_x = h_y->GetBinCenter(biy);
859 ff_fit->SetParameters(conMax, conMax_x, h_y->GetRMS() * 0.75, 0., 0.);
860 ff_fit->FixParameter(4, 0.);
862 double x_min =
rpc.x_min_fit_mode_, x_max =
rpc.x_max_fit_mode_;
863 h_y->Fit(ff_fit.get(),
"Q",
"", x_min, x_max);
865 ff_fit->ReleaseParameter(4);
866 double w =
std::min(4., 2. * ff_fit->GetParameter(2));
867 x_min = ff_fit->GetParameter(1) -
w;
868 x_max =
std::min(
rpc.y_max_fit_mode_, ff_fit->GetParameter(1) +
w);
870 h_y->Fit(ff_fit.get(),
"Q",
"", x_min, x_max);
875 double y_mode =
findMax(ff_fit.get());
876 const double y_mode_fit_unc = ff_fit->GetParameter(2) / 10;
877 const double y_mode_sys_unc =
cfg.y_mode_sys_unc();
878 double y_mode_unc =
std::sqrt(y_mode_fit_unc * y_mode_fit_unc + y_mode_sys_unc * y_mode_sys_unc);
880 const double chiSqThreshold =
cfg.chiSqThreshold();
883 !(std::fabs(y_mode_unc) >
cfg.y_mode_unc_max_valid() || std::fabs(y_mode) >
cfg.y_mode_max_valid() ||
884 ff_fit->GetChisquare() / ff_fit->GetNDF() > chiSqThreshold);
887 auto g_data = std::make_unique<TGraph>();
888 g_data->SetPoint(0, y_mode, y_mode_unc);
889 g_data->SetPoint(1, ff_fit->GetChisquare(), ff_fit->GetNDF());
890 g_data->SetPoint(2,
valid, 0.);
891 g_data->Write(
"g_data");
897 h_mode->Fill(
x, y_mode);
898 h_mode->setBinError(bix, y_mode_unc);
901 return h_mode->getTH1D();
907 TDirectory* yAliDir =
nullptr;
911 auto ff = std::make_unique<TF1>(
"ff",
"[0] + [1]*(x - [2])");
912 auto ff_sl_fix = std::make_unique<TF1>(
"ff_sl_fix",
"[0] + [1]*(x - [2])");
915 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
916 for (
const auto&
rpc : {sc.rp_F_, sc.rp_N_}) {
917 TDirectory* rpDir =
nullptr;
919 rpDir = yAliDir->mkdir(
rpc.name_.c_str());
920 gDirectory = rpDir->mkdir(
"x");
924 iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/multiplicity selection/" +
rpc.name_ +
"/h2_y_vs_x");
926 if (h2_y_vs_x ==
nullptr) {
927 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[y_alignment] " <<
rpc.name_ <<
": cannot load data, skipping";
934 if ((
unsigned int)h_y_cen_vs_x->GetEntries() <
cfg.modeGraphMinN()) {
936 <<
"[y_alignment] " <<
rpc.name_ <<
": insufficient data, skipping (mode graph " 937 << h_y_cen_vs_x->GetEntries() <<
"/" <<
cfg.modeGraphMinN() <<
")";
941 const double x_min =
cfg.alignment_y_ranges().at(
rpc.id_).x_min_;
942 const double x_max =
cfg.alignment_y_ranges().at(
rpc.id_).x_max_;
948 ff->SetParameters(0., 0., 0.);
949 ff->FixParameter(2, -sh_x);
951 h_y_cen_vs_x->Fit(
ff.get(),
"Q",
"", x_min, x_max);
953 const double a =
ff->GetParameter(1), a_unc =
ff->GetParError(1);
954 const double b =
ff->GetParameter(0), b_unc =
ff->GetParError(0);
957 <<
"[y_alignment] " <<
rpc.name_ <<
":\n" 958 <<
std::fixed << std::setprecision(3) <<
" x_min = " << x_min <<
", x_max = " << x_max <<
"\n" 959 <<
" sh_x = " << sh_x <<
", slope (fix) = " <<
slope <<
", slope (fitted) = " <<
a;
961 CTPPSRPAlignmentCorrectionData rpResult(0., 0.,
b, b_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
965 ff_sl_fix->SetParameters(0., 0., 0.);
966 ff_sl_fix->FixParameter(1,
slope);
967 ff_sl_fix->FixParameter(2, -sh_x);
968 ff_sl_fix->SetLineColor(4);
969 h_y_cen_vs_x->Fit(ff_sl_fix.get(),
"Q+",
"", x_min, x_max);
971 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
973 CTPPSRPAlignmentCorrectionData rpResult_sl_fix(0., 0., b_fs, b_fs_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
977 <<
"[y_alignment] " <<
std::fixed << std::setprecision(3) <<
"ff: " <<
ff->GetParameter(0) <<
" + " 978 <<
ff->GetParameter(1) <<
" * (x - " <<
ff->GetParameter(2) <<
"), ff_sl_fix: " << ff_sl_fix->GetParameter(0)
979 <<
" + " << ff_sl_fix->GetParameter(1) <<
" * (x - " << ff_sl_fix->GetParameter(2) <<
")";
984 h_y_cen_vs_x->SetTitle(
";x (mm); mode of y (mm)");
985 h_y_cen_vs_x->Write(
"h_y_cen_vs_x");
987 auto g_results = std::make_unique<TGraph>();
988 g_results->SetPoint(0, sh_x, 0.);
989 g_results->SetPoint(1,
a, a_unc);
990 g_results->SetPoint(2,
b, b_unc);
991 g_results->SetPoint(3, b_fs, b_fs_unc);
992 g_results->Write(
"g_results");
1012 TH2D*
h,
const double a,
const double c,
const double n_si,
const double si,
const std::string&
label) {
1013 auto canvas = std::make_unique<TCanvas>();
1019 double x_min = -30.;
1022 auto g_up = std::make_unique<TGraph>();
1023 g_up->SetName(
"g_up");
1024 g_up->SetPoint(0, x_min, -
a * x_min -
c + n_si * si);
1025 g_up->SetPoint(1, x_max, -
a * x_max -
c + n_si * si);
1026 g_up->SetLineColor(1);
1029 auto g_down = std::make_unique<TGraph>();
1030 g_down->SetName(
"g_down");
1031 g_down->SetPoint(0, x_min, -
a * x_min -
c - n_si * si);
1032 g_down->SetPoint(1, x_max, -
a * x_max -
c - n_si * si);
1033 g_down->SetLineColor(1);
1043 std::unique_ptr<TH1D>
hist;
1045 hist = std::make_unique<TH1D>(
title.c_str(),
labels.c_str(), 0, -10., 10.);
1046 }
else if (
n == 1) {
1047 hist = std::make_unique<TH1D>(
title.c_str(),
labels.c_str(), 1, graph->GetPointX(0) - 5., graph->GetPointX(0) + 5.);
1049 n =
n == -1 ? graph->GetN() :
n;
1050 binWidth = binWidth == -1 ? graph->GetPointX(1) - graph->GetPointX(0) : binWidth;
1051 double diff = binWidth / 2.;
1053 double max =
min +
n * binWidth;
1057 for (
int i = 0;
i < graph->GetN();
i++) {
1059 graph->GetPoint(
i,
x,
y);
1061 hist->SetBinError(
hist->GetXaxis()->FindBin(
x), graph->GetErrorY(
i));
1070 unsigned int arm = shortId / 100;
1071 unsigned int station = (shortId / 10) % 10;
1072 unsigned int rp = shortId % 10;
1079 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.
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