27 #include "TGraphErrors.h"
68 for (
int bi = 1; bi <=
p->GetNbinsX(); ++bi) {
69 double c =
p->GetBinCenter(bi);
71 double N =
p->GetBinEntries(bi);
72 double Sy =
p->GetBinContent(bi) *
N;
73 double Syy =
p->GetSumw2()->At(bi);
75 double si_sq = Syy /
N - Sy * Sy /
N /
N;
76 double si = (si_sq >= 0.) ?
sqrt(si_sq) : 0.;
77 double si_unc_sq = si_sq / 2. /
N;
78 double si_unc = (si_unc_sq >= 0.) ?
sqrt(si_unc_sq) : 0.;
81 g->SetPoint(
idx,
c, si);
82 g->SetPointError(
idx, 0., si_unc);
94 struct SingleRPPlots {
96 std::unique_ptr<TH1D>
h_xi;
105 h_xi(new TH1D(
"",
";#xi", 100, 0., 0.3)),
106 h2_th_y_vs_xi(new TH2D(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
107 p_th_y_vs_xi(new TProfile(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3)),
108 h_xi_n1f1(new TH1D(
"",
";#xi", 100, 0., 0.3)) {
109 for (
unsigned int n = 2;
n <= 10; ++
n)
117 const double th_y =
p.thetaY();
123 it->second->Fill(
p.xi());
137 TDirectory *d_top = gDirectory;
139 gDirectory = d_top->mkdir(
"h_xi_nTracks");
142 sprintf(
buf,
"h_xi_nTracks_%u",
p.first);
143 p.second->Write(
buf);
178 :
h_multiplicity(new TH1D(
"",
";reconstructed protons per event", 11, -0.5, 10.5)),
179 h_xi(new TH1D(
"",
";#xi", 100, 0., 0.3)),
180 h_th_x(new TH1D(
"",
";#theta_{x} (rad)", 250, -500E-6, +500E-6)),
181 h_th_y(new TH1D(
"",
";#theta_{y} (rad)", 500, -1000E-6, +1000E-6)),
182 h_vtx_y(new TH1D(
"",
";vtx_{y} (cm)", 100, -100E-3, +100E-3)),
183 h_chi_sq(new TH1D(
"",
";#chi^{2}", 100, 0., 10.)),
184 h_log_chi_sq(new TH1D(
"",
";log_{10} #chi^{2}", 100, -20., 5.)),
186 h_time(new TH1D(
"",
";time (ns)", 100, -2., +2.)),
187 h_time_unc(new TH1D(
"",
";time unc (ns)", 100, -1., +1.)),
192 h2_th_x_vs_xi(new TH2D(
"",
";#xi;#theta_{x} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
193 h2_th_y_vs_xi(new TH2D(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
194 h2_vtx_y_vs_xi(new TH2D(
"",
";#xi;vtx_{y} (cm)", 100, 0., 0.3, 100, -100E-3, +100E-3)),
195 p_th_x_vs_xi(new TProfile(
"",
";#xi;#theta_{x} (rad)", 100, 0., 0.3)),
196 p_th_y_vs_xi(new TProfile(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3)),
197 p_vtx_y_vs_xi(new TProfile(
"",
";#xi;vtx_{y} (cm)", 100, 0., 0.3)),
199 new TH2D(
"",
";reco protons per event;timing tracks per event", 11, -0.5, 10.5, 11, -0.5, 10.5)),
200 h_xi_n1f1(new TH1D(
"",
";#xi", 100, 0., 0.3)),
203 new TH2D(
"",
";x_tracking (mm);x_timing (mm)", 100, 0., 20., 100, 0., 20.)),
210 new TH1D(
"",
";match between tracking and timing tracks", 2, -0.5, +1.5)),
215 std::vector<double> v_t_bin_edges;
216 for (
double t = 0;
t <= 5.;) {
217 v_t_bin_edges.push_back(
t);
218 const double de_t = 0.05 + 0.09 *
t + 0.02 *
t *
t;
221 h_t_unif = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", 100, 0., 5.);
222 h_t = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
223 h_t_xi_range1 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
224 h_t_xi_range2 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
225 h_t_xi_range3 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
227 "",
";#xi;|t| (GeV^2)", 100, 0., 0.3, v_t_bin_edges.size() - 1, v_t_bin_edges.data());
229 for (
unsigned int n = 2;
n <= 10; ++
n)
237 unsigned int n_contrib_tracking_tracks = 0, n_contrib_timing_tracks = 0;
238 for (
const auto &tr :
p.contributingLocalTracks()) {
241 n_contrib_tracking_tracks++;
243 n_contrib_timing_tracks++;
246 const double th_x =
p.thetaX();
247 const double th_y =
p.thetaY();
248 const double mt = -
p.t();
267 if (
p.xi() > 0.04 &&
p.xi() < 0.07)
269 if (
p.xi() > 0.07 &&
p.xi() < 0.10)
271 if (
p.xi() > 0.10 &&
p.xi() < 0.13)
274 if (
p.timeError() > 0.) {
292 it->second->Fill(
p.xi());
315 auto g_th_x_RMS_vs_xi = std::make_unique<TGraphErrors>();
317 g_th_x_RMS_vs_xi->Write(
"g_th_x_RMS_vs_xi");
322 auto g_th_y_RMS_vs_xi = std::make_unique<TGraphErrors>();
324 g_th_y_RMS_vs_xi->Write(
"g_th_y_RMS_vs_xi");
329 auto g_vtx_y_RMS_vs_xi = std::make_unique<TGraphErrors>();
331 g_vtx_y_RMS_vs_xi->Write(
"g_vtx_y_RMS_vs_xi");
333 h_t->Scale(1.,
"width");
348 TDirectory *d_top = gDirectory;
350 gDirectory = d_top->mkdir(
"h_xi_nTracks");
353 sprintf(
buf,
"h_xi_nTracks_%u",
p.first);
354 p.second->Write(
buf);
390 h_xi_diff_mu_si(new TH1D(
"",
";#xi_{multi} - #xi_{single}", 100, -0.1, +0.1)),
391 h_xi_diff_si_mu(new TH1D(
"",
";#xi_{single} - #xi_{multi}", 100, -0.1, +0.1)),
393 new TH2D(
"",
";#xi_{multi};#xi_{single} - #xi_{multi}", 100, 0., 0.3, 100, -0.10, 0.10)),
396 new TH2D(
"",
";#theta^{*}_{y,si};#theta^{*}_{y,mu}", 100, -500E-6, +500E-6, 100, -500E-6, +500E-6)) {}
407 const double th_y_si = p_single.
thetaY();
408 const double th_y_mu = p_multi.
thetaY();
440 h_th_y_si_diffNF(new TH1D(
"",
";#theta_{y,sF} - #theta_{y,sN}", 100, -100E-6, +100E-6)),
447 const double th_y_s_N = p_s_N.
thetaY();
448 const double th_y_s_F = p_s_F.
thetaY();
485 tokenRecoProtonsSingleRP_(
487 tokenRecoProtonsMultiRP_(
490 rpId_45_N_(ps.getParameter<unsigned
int>(
"rpId_45_N")),
491 rpId_45_F_(ps.getParameter<unsigned
int>(
"rpId_45_F")),
492 rpId_56_N_(ps.getParameter<unsigned
int>(
"rpId_56_N")),
493 rpId_56_F_(ps.getParameter<unsigned
int>(
"rpId_56_F")),
495 outputFile_(ps.getParameter<
string>(
"outputFile")),
496 maxNonEmptyEvents_(ps.getUntrackedParameter<signed
int>(
"maxNonEmptyEvents", -1)),
498 p_x_L_diffNF_vs_x_L_N_(new TProfile(
"p_x_L_diffNF_vs_x_L_N",
";x_{LN};x_{LF} - x_{LN}", 100, 0., +20.)),
499 p_x_R_diffNF_vs_x_R_N_(new TProfile(
"p_x_R_diffNF_vs_x_R_N",
";x_{RN};x_{RF} - x_{RN}", 100, 0., +20.)),
501 p_y_L_diffNF_vs_y_L_N_(new TProfile(
"p_y_L_diffNF_vs_y_L_N",
";y_{LN};y_{LF} - y_{LN}", 100, -20., +20.)),
502 p_y_R_diffNF_vs_y_R_N_(new TProfile(
"p_y_R_diffNF_vs_y_R_N",
";y_{RN};y_{RF} - y_{RN}", 100, -20., +20.)),
504 n_non_empty_events_(0) {
506 const unsigned int arm = (sector ==
"45") ? 0 : 1;
524 const double z_i =
geometry.rpTranslation(tr_i.rpId()).
z();
525 const double z_j =
geometry.rpTranslation(tr_j.rpId()).
z();
528 const double z_ti = -
geometry.rpTranslation(tr_ti.
rpId()).
z();
529 const double f_i = (z_ti - z_j) / (z_i - z_j), f_j = (z_i - z_ti) / (z_i - z_j);
530 const double x_inter = f_i * tr_i.x() + f_j * tr_j.x();
531 const double x_inter_unc_sq = f_i * f_i * tr_i.xUnc() * tr_i.xUnc() + f_j * f_j * tr_j.xUnc() * tr_j.xUnc();
537 de_x = tr_ti.
x() - x_inter;
538 de_x_unc =
sqrt(tr_ti.
xUnc() * tr_ti.
xUnc() + x_inter_unc_sq);
554 if (!hRecoProtonsSingleRP->empty())
558 throw cms::Exception(
"CTPPSProtonReconstructionPlotter") <<
"Number of non empty events reached maximum.";
569 std::map<unsigned int, unsigned int> armTrackCounter, armTimingTrackCounter;
570 std::map<unsigned int, unsigned int> armTrackCounter_N, armTrackCounter_F;
572 for (
const auto &tr : *hTracks) {
574 unsigned int decRPId =
rpId.arm() * 100 +
rpId.station() * 10 +
rpId.rp();
578 armTrackCounter_N[0]++;
582 armTrackCounter_F[0]++;
586 armTrackCounter_N[1]++;
590 armTrackCounter_F[1]++;
593 armTrackCounter[
rpId.arm()]++;
595 const bool trackerRP =
598 armTimingTrackCounter[
rpId.arm()]++;
601 if (tr_L_N && tr_L_F) {
606 if (tr_R_N && tr_R_F) {
612 std::map<unsigned int, unsigned int> singleRPMultiplicity, multiRPMultiplicity;
615 multiRPMultiplicity[0] = multiRPMultiplicity[1] = 0;
618 for (
const auto &proton : *hRecoProtonsSingleRP) {
620 unsigned int decRPId =
rpId.arm() * 100 +
rpId.station() * 10 +
rpId.rp();
622 const bool n1f1 = (armTrackCounter_N[
rpId.arm()] == 1 && armTrackCounter_F[
rpId.arm()] == 1);
626 if (proton.validFit())
627 singleRPMultiplicity[decRPId]++;
630 for (
const auto it : singleRPMultiplicity)
634 for (
const auto &proton : *hRecoProtonsMultiRP) {
636 unsigned int armId =
rpId.arm();
638 const bool n1f1 = (armTrackCounter_N[armId] == 1 && armTrackCounter_F[armId] == 1);
640 multiRPPlots_[armId].fill(proton, armTrackCounter[armId], n1f1);
642 if (proton.validFit())
643 multiRPMultiplicity[armId]++;
646 for (
const auto it : multiRPMultiplicity) {
648 pl.h_multiplicity->Fill(it.second);
649 pl.h2_timing_tracks_vs_prot_mult->Fill(it.second, armTimingTrackCounter[it.first]);
653 map<unsigned int, bool> clCo;
654 clCo[0] = (singleRPMultiplicity[
rpId_45_N_] && singleRPMultiplicity[
rpId_45_F_] && multiRPMultiplicity[0] == 1);
655 clCo[1] = (singleRPMultiplicity[
rpId_56_N_] && singleRPMultiplicity[
rpId_56_F_] && multiRPMultiplicity[1] == 1);
658 for (
const auto &proton : *hRecoProtonsMultiRP) {
659 if (!proton.validFit())
662 CTPPSDetId rpId_proton((*proton.contributingLocalTracks().begin())->
rpId());
663 unsigned int armId = rpId_proton.
arm();
666 for (
const auto &tr : *hTracks) {
668 if (rpId_tr.arm() != armId)
671 const bool trackerRP =
676 double x_tr = -1., x_ti = -1.;
677 double de_x = 0., de_x_unc = 0.;
680 const double rd = (de_x_unc > 0.) ?
de_x / de_x_unc : -1E10;
682 const bool match = (ac.ti_tr_min <= fabs(rd) && fabs(rd) <= ac.ti_tr_max);
684 pl.h_de_x_timing_vs_tracking->Fill(
de_x);
685 pl.h_de_x_rel_timing_vs_tracking->Fill(rd);
686 pl.h_de_x_match_timing_vs_tracking->Fill(
match ? 1. : 0.);
688 if (clCo[armId] && armTimingTrackCounter[armId] == 1) {
689 pl.h2_x_timing_vs_x_tracking_ClCo->Fill(x_tr, x_ti);
691 pl.h_de_x_timing_vs_tracking_ClCo->Fill(
de_x);
692 pl.h_de_x_rel_timing_vs_tracking_ClCo->Fill(rd);
693 pl.h_de_x_match_timing_vs_tracking_ClCo->Fill(
match ? 1. : 0.);
695 pl.p_time_unc_vs_x_ClCo->Fill(x_tr, proton.timeError());
701 for (
const auto &proton : *hRecoProtonsMultiRP) {
702 if (!proton.validFit())
706 unsigned int armId =
rpId.arm();
708 const auto &nTimingTracks = armTimingTrackCounter[armId];
713 double x_ref = 0., y_ref = 0.;
723 if (nTimingTracks == 0)
724 pl.h2_y_vs_x_tt0_ClCo->Fill(x_ref, y_ref);
725 if (nTimingTracks == 1)
726 pl.h2_y_vs_x_tt1_ClCo->Fill(x_ref, y_ref);
727 if (nTimingTracks > 1)
728 pl.h2_y_vs_x_ttm_ClCo->Fill(x_ref, y_ref);
732 for (
const auto &proton_m : *hRecoProtonsMultiRP) {
733 CTPPSDetId rpId_m((*proton_m.contributingLocalTracks().begin())->
rpId());
734 unsigned int arm = rpId_m.
arm();
738 for (
const auto &proton_s : *hRecoProtonsSingleRP) {
741 bool compatible =
false;
742 for (
const auto &tr_m : proton_m.contributingLocalTracks()) {
743 if (tr_m.key() == key_s) {
753 CTPPSDetId rpId_s((*proton_s.contributingLocalTracks().begin())->
rpId());
754 const unsigned int idx = rpId_s.arm() * 1000 + rpId_s.station() * 100 + rpId_s.rp() * 10 + rpId_s.arm();
758 const unsigned int rpDecId_s = rpId_s.arm() * 100 + rpId_s.station() * 10 + rpId_s.rp();
776 auto f_out = std::make_unique<TFile>(
outputFile_.c_str(),
"recreate");
784 TDirectory *d_singleRPPlots = f_out->mkdir(
"singleRPPlots");
786 gDirectory = d_singleRPPlots->mkdir(Form(
"rp%u", it.first));
790 TDirectory *d_multiRPPlots = f_out->mkdir(
"multiRPPlots");
792 gDirectory = d_multiRPPlots->mkdir(Form(
"arm%u", it.first));
796 TDirectory *d_singleMultiCorrelationPlots = f_out->mkdir(
"singleMultiCorrelationPlots");
798 unsigned int si_rp = it.first / 10;
799 unsigned int mu_arm = it.first % 10;
801 gDirectory = d_singleMultiCorrelationPlots->mkdir(Form(
"si_rp%u_mu_arm%u", si_rp, mu_arm));
805 TDirectory *d_armCorrelationPlots = f_out->mkdir(
"armCorrelationPlots");
807 gDirectory = d_armCorrelationPlots->mkdir(Form(
"arm%u", it.first));