40 #include "TGraphErrors.h" 65 std::unique_ptr<TGraphErrors>
buildGraphFromVector(
const std::vector<PPSAlignmentConfiguration::PointErrors>&
pv);
68 const std::vector<MonitorElement*>& mes,
69 const unsigned int fitProfileMinBinEntries,
70 const unsigned int fitProfileMinNReasonable);
93 static double findMax(
const TF1* ff_fit);
103 TH2D*
h,
const double a,
const double c,
const double si,
const double n_si,
const std::string&
label);
108 double binWidth = -1.,
146 dqmDir_(iConfig.getParameter<
std::
string>(
"dqm_dir")),
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.)),
154 yCorrRange_(
std::make_pair(iConfig.getParameter<double>(
"y_corr_min") / 1000.,
155 iConfig.getParameter<double>(
"y_corr_max") / 1000.)),
156 debug_(iConfig.getParameter<
bool>(
"debug")) {
158 if (!textResultsPath.empty()) {
162 debugFile_ = std::make_unique<TFile>(
"debug_harvester.root",
"recreate");
165 edm::LogInfo(
"PPSAlignmentHarvester").log([&](
auto& li) {
166 li <<
"parameters:\n";
167 li <<
"* dqm_dir: " <<
dqmDir_ <<
"\n";
168 li <<
"* sequence:\n";
170 li <<
" " <<
i + 1 <<
": " <<
sequence_[
i] <<
"\n";
172 li <<
"* overwrite_sh_x: " << std::boolalpha <<
overwriteShX_ <<
"\n";
173 li <<
"* text_results_path: " << textResultsPath <<
"\n";
182 li <<
"* debug: " << std::boolalpha <<
debug_ <<
"\n";
196 desc.add<std::vector<std::string>>(
"sequence", {
"x_alignment",
"x_alignment_relative",
"y_alignment"});
197 desc.add<
bool>(
"overwrite_sh_x",
true);
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);
222 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
223 for (
const auto&
rpc : {sc.rp_N_, sc.rp_F_}) {
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")
238 bool doXAli =
false, doXAliRel =
false, doYAli =
false;
240 if (aliMethod ==
"x_alignment") {
243 }
else if (aliMethod ==
"x_alignment_relative") {
246 }
else if (aliMethod ==
"y_alignment") {
250 edm::LogError(
"PPSAlignmentHarvester") << aliMethod <<
" is a wrong method name.";
259 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
264 double d_x_rel_N, d_x_rel_F;
274 double b = d_x_rel_N - d_x_rel_F;
275 double xCorrRel =
b + d_x_F - d_x_N;
277 CTPPSRPAlignmentCorrectionData corrRelN(xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
279 CTPPSRPAlignmentCorrectionData corrRelF(-xCorrRel / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
293 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
294 for (
const auto&
rpc : {sc.rp_F_, sc.rp_N_}) {
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.);
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.);
316 edm::LogInfo(
"PPSAlignmentHarvester") <<
"final merged results:\n" << finalResults;
326 poolDbService->
writeOneIOV(finalResults, poolDbService->
currentTime(),
"CTPPSRPAlignmentCorrectionsDataRcd");
329 <<
"Could not store the results in a DB object. PoolDBService not available.";
335 TDirectory* cutsDir =
debugFile_->mkdir(
"cuts");
336 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
337 TDirectory* sectorDir = cutsDir->mkdir(sc.name_.c_str());
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");
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");
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");
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");
360 const std::vector<PPSAlignmentConfiguration::PointErrors>&
pv) {
361 auto g = std::make_unique<TGraphErrors>();
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_);
377 const std::vector<MonitorElement*>& mes,
378 const unsigned int fitProfileMinBinEntries,
379 const unsigned int fitProfileMinNReasonable) {
380 auto g = std::make_unique<TGraphErrors>();
382 for (
auto*
me : mes) {
383 if (
me->getName() ==
"h_y")
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));
393 TH1D* h_y =
me->getTH1D();
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;
401 TProfile* p_y_diffFN_vs_y = p_y_diffFN_vs_y_monitor->getTProfile();
403 double y_cen = h_y->GetMean() +
rpc.y_cen_add_;
404 double y_width = h_y->GetRMS() *
rpc.y_width_mult_;
408 p_y_diffFN_vs_y, y_cen, y_width, fitProfileMinBinEntries, fitProfileMinNReasonable, sl, sl_unc);
413 p_y_diffFN_vs_y->Write(parentName.c_str());
416 g->SetPoint(
idx, (x_max + x_min) / 2., sl);
417 g->SetPointError(
idx, (x_max - x_min) / 2., sl_unc);
430 TGraphErrors* g_test,
435 double& sh_best_unc) {
436 const auto range_test =
cfg.alignment_x_meth_o_ranges().at(
rpc.id_);
440 <<
"ref: x_min = " << range_ref.
x_min_ <<
", x_max = " << range_ref.
x_max_ 442 <<
"test: x_min = " << range_test.x_min_ <<
", x_max = " << range_test.x_max_;
445 auto s_ref = std::make_unique<TSpline3>(
"s_ref", g_ref->GetX(), g_ref->GetY(), g_ref->GetN());
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");
459 double S2_norm_best = 1E100;
461 for (
double sh = sh_min; sh <= sh_max; sh +=
cfg.x_ali_sh_step()) {
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);
471 const double x_ref = x_test + sh;
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_)
477 const double y_ref = s_ref->Eval(x_ref);
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) {
487 if (
x > x_ref &&
x < xg) {
495 const double y_ref_unc = (g_ref->GetErrorY(js) + g_ref->GetErrorY(jg)) / 2.;
498 const double S2_inc =
pow(y_test - y_ref, 2.) / (y_ref_unc * y_ref_unc + y_test_unc * y_test_unc);
503 double S2_norm = S2 / n_points;
505 if (S2_norm < S2_norm_best) {
506 S2_norm_best = S2_norm;
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);
517 auto ff_pol2 = std::make_unique<TF1>(
"ff_pol2",
"[0] + [1]*x + [2]*x*x");
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));
526 <<
"sh_best = (" << sh_best <<
" +- " << sh_best_unc <<
") mm";
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;
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());
541 g_chi_sq_norm->Write();
542 g_test_shifted->SetTitle(
";x (mm);S");
543 g_test_shifted->Write(
"g_test_shifted");
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_);
554 auto c_cmp = std::make_unique<TCanvas>(
"c_cmp");
555 g_ref->SetLineColor(1);
556 g_ref->SetName(
"g_ref");
559 g_test->SetLineColor(4);
560 g_test->SetName(
"g_test");
563 g_test_shifted->SetLineColor(2);
564 g_test_shifted->SetName(
"g_test_shifted");
566 g_test_shifted->Draw(
"pl");
576 TDirectory* xAliDir =
nullptr;
580 for (
const auto& [sc, sc_ref] : {std::make_pair(
cfg.sectorConfig45(), cfg_ref.
sectorConfig45()),
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_)}) {
585 if (mes_test.empty()) {
586 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[x_alignment] " <<
rpc.name_ <<
": could not load mes_test";
590 TDirectory* rpDir =
nullptr;
592 rpDir = xAliDir->mkdir(
rpc.name_.c_str());
595 if (vec_ref.empty()) {
596 edm::LogInfo(
"PPSAlignmentHarvester") <<
"[x_alignment] " <<
rpc.name_ <<
": reference points vector is empty";
603 gDirectory = rpDir->mkdir(
"fits_test");
605 iGetter,
rpc, mes_test,
cfg.fitProfileMinBinEntries(),
cfg.fitProfileMinNReasonable());
608 if (g_ref->GetN() < (
int)
cfg.methOGraphMinN() || g_test->GetN() < (
int)
cfg.methOGraphMinN()) {
610 <<
"[x_alignment] " <<
rpc.name_ <<
": insufficient data, skipping (g_ref " << g_ref->GetN() <<
"/" 611 <<
cfg.methOGraphMinN() <<
", g_test " << g_test->GetN() <<
"/" <<
cfg.methOGraphMinN() <<
")";
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());
623 iBooker.
book1DD(
"h_test", histPtr.get());
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");
633 const auto& shiftRange =
cfg.matchingShiftRanges().at(
rpc.id_);
634 double sh = 0., sh_unc = 0.;
649 CTPPSRPAlignmentCorrectionData rpResult(sh, sh_unc, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
652 <<
"Setting sh_x of " <<
rpc.name_ <<
" to " << sh;
672 TDirectory* xAliRelDir =
nullptr;
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])");
680 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
681 TDirectory* sectorDir =
nullptr;
683 sectorDir = xAliRelDir->mkdir(sc.name_.c_str());
684 gDirectory = sectorDir;
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) {
690 <<
"[x_alignment_relative] " << sc.name_ <<
": cannot load data, skipping";
693 TProfile* p_x_diffFN_vs_x_N = p_x_diffFN_vs_x_N_monitor->getTProfile();
695 if (p_x_diffFN_vs_x_N->GetEntries() <
cfg.nearFarMinEntries()) {
697 <<
"[x_alignment_relative] " << sc.name_ <<
": insufficient data, skipping (near_far " 698 << p_x_diffFN_vs_x_N->GetEntries() <<
"/" <<
cfg.nearFarMinEntries() <<
")";
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_;
705 const double sh_x_N =
sh_x_map_[sc.rp_N_.id_];
706 double slope = sc.slope_;
709 ff->SetParameters(0.,
slope, 0.);
710 ff->FixParameter(2, -sh_x_N);
712 p_x_diffFN_vs_x_N->Fit(
ff.get(),
"Q",
"", x_min, x_max);
714 const double a =
ff->GetParameter(1), a_unc =
ff->GetParError(1);
715 const double b =
ff->GetParameter(0), b_unc =
ff->GetParError(0);
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;
722 CTPPSRPAlignmentCorrectionData rpResult_N(+
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
724 CTPPSRPAlignmentCorrectionData rpResult_F(-
b / 2., b_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
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);
734 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
736 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_N(+b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
738 CTPPSRPAlignmentCorrectionData rpResult_sl_fix_F(-b_fs / 2., b_fs_unc / 2., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
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) <<
")";
748 iBooker.
bookProfile(
"p_x_diffFN_vs_x_N", p_x_diffFN_vs_x_N);
751 p_x_diffFN_vs_x_N->Write(
"p_x_diffFN_vs_x_N");
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");
776 const double mu = ff_fit->GetParameter(1);
777 const double si = ff_fit->GetParameter(2);
780 if (si > 25. || std::fabs(
mu) > 100.)
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);
800 TDirectory* d_top =
nullptr;
804 auto ff_fit = std::make_unique<TF1>(
"ff_fit",
"[0] * exp(-(x-[1])*(x-[1])/2./[2]/[2]) + [3] + [4]*x");
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)",
811 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(1) -
diff,
812 h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(h_n) +
diff);
815 for (
int bix = 1; bix <= h_n; bix++) {
816 const double x = h2_y_vs_x->
getTH2D()->GetXaxis()->GetBinCenter(bix);
819 sprintf(
buf,
"h_y_x=%.3f",
x);
820 TH1D* h_y = h2_y_vs_x->
getTH2D()->ProjectionY(
buf, bix, bix);
822 if (h_y->GetEntries() <
cfg.multSelProjYMinEntries())
826 sprintf(
buf,
"x=%.3f",
x);
827 gDirectory = d_top->mkdir(
buf);
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);
839 ff_fit->SetParameters(conMax, conMax_x, h_y->GetRMS() * 0.75, 0., 0.);
840 ff_fit->FixParameter(4, 0.);
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);
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);
850 h_y->Fit(ff_fit.get(),
"Q",
"", x_min, x_max);
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);
860 const double chiSqThreshold =
cfg.chiSqThreshold();
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);
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");
877 h_mode->Fill(
x, y_mode);
878 h_mode->setBinError(bix, y_mode_unc);
881 return h_mode->getTH1D();
887 TDirectory* yAliDir =
nullptr;
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])");
895 for (
const auto& sc : {
cfg.sectorConfig45(),
cfg.sectorConfig56()}) {
896 for (
const auto&
rpc : {sc.rp_F_, sc.rp_N_}) {
897 TDirectory* rpDir =
nullptr;
899 rpDir = yAliDir->mkdir(
rpc.name_.c_str());
900 gDirectory = rpDir->mkdir(
"x");
904 iGetter.
get(
dqmDir_ +
"/worker/" + sc.name_ +
"/multiplicity selection/" +
rpc.name_ +
"/h2_y_vs_x");
906 if (h2_y_vs_x ==
nullptr) {
907 edm::LogWarning(
"PPSAlignmentHarvester") <<
"[y_alignment] " <<
rpc.name_ <<
": cannot load data, skipping";
914 if ((
unsigned int)h_y_cen_vs_x->GetEntries() <
cfg.modeGraphMinN()) {
916 <<
"[y_alignment] " <<
rpc.name_ <<
": insufficient data, skipping (mode graph " 917 << h_y_cen_vs_x->GetEntries() <<
"/" <<
cfg.modeGraphMinN() <<
")";
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_;
928 ff->SetParameters(0., 0., 0.);
929 ff->FixParameter(2, -sh_x);
931 h_y_cen_vs_x->Fit(
ff.get(),
"Q",
"", x_min, x_max);
933 const double a =
ff->GetParameter(1), a_unc =
ff->GetParError(1);
934 const double b =
ff->GetParameter(0), b_unc =
ff->GetParError(0);
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;
941 CTPPSRPAlignmentCorrectionData rpResult(0., 0.,
b, b_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
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);
951 const double b_fs = ff_sl_fix->GetParameter(0), b_fs_unc = ff_sl_fix->GetParError(0);
953 CTPPSRPAlignmentCorrectionData rpResult_sl_fix(0., 0., b_fs, b_fs_unc, 0., 0., 0., 0., 0., 0., 0., 0.);
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) <<
")";
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");
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");
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>();
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);
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);
1023 std::unique_ptr<TH1D>
hist;
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.);
1029 n =
n == -1 ? graph->GetN() :
n;
1030 binWidth = binWidth == -1 ? graph->GetPointX(1) - graph->GetPointX(0) : binWidth;
1031 double diff = binWidth / 2.;
1033 double max =
min +
n * binWidth;
1037 for (
int i = 0;
i < graph->GetN();
i++) {
1039 graph->GetPoint(
i,
x,
y);
1041 hist->SetBinError(
hist->GetXaxis()->FindBin(
x), graph->GetErrorY(
i));
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)
std::map< unsigned int, double > sh_x_map_
edm::ESGetToken< PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd > esTokenReference_
virtual void setCurrentFolder(std::string const &fullpath)
std::ofstream textResultsFile_
#define DEFINE_FWK_MODULE(type)
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)
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
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)
bool getData(T &iHolder) const
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
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)
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