29 #include "TGraphErrors.h" 60 for (
int bi = 1; bi <=
p->GetNbinsX(); ++bi) {
61 double c =
p->GetBinCenter(bi);
63 double N =
p->GetBinEntries(bi);
64 double Sy =
p->GetBinContent(bi) *
N;
65 double Syy =
p->GetSumw2()->At(bi);
67 double si_sq = Syy /
N - Sy * Sy /
N /
N;
68 double si = (si_sq >= 0.) ?
sqrt(si_sq) : 0.;
69 double si_unc_sq = si_sq / 2. /
N;
70 double si_unc = (si_unc_sq >= 0.) ?
sqrt(si_unc_sq) : 0.;
73 g->SetPoint(
idx,
c, si);
74 g->SetPointError(
idx, 0., si_unc);
88 std::unique_ptr<TH1D>
h_xi;
96 :
h_multiplicity(new TH1D(
"",
";reconstructed protons", 11, -0.5, 10.5)),
97 h_xi(new TH1D(
"",
";#xi", 100, 0., 0.3)),
98 h2_th_y_vs_xi(new TH2D(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
99 p_th_y_vs_xi(new TProfile(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3)),
100 h_xi_n1f1(new TH1D(
"",
";#xi", 100, 0., 0.3)) {
101 for (
unsigned int n = 2;
n <= 10; ++
n)
109 const double th_y =
p.thetaY();
115 it->second->Fill(
p.xi());
129 TDirectory *d_top = gDirectory;
131 gDirectory = d_top->mkdir(
"h_xi_nTracks");
134 sprintf(
buf,
"h_xi_nTracks_%u",
p.first);
135 p.second->Write(
buf);
170 :
h_multiplicity(new TH1D(
"",
";reconstructed protons per event", 11, -0.5, 10.5)),
171 h_xi(new TH1D(
"",
";#xi", 100, 0., 0.3)),
172 h_th_x(new TH1D(
"",
";#theta_{x} (rad)", 250, -500E-6, +500E-6)),
173 h_th_y(new TH1D(
"",
";#theta_{y} (rad)", 500, -1000E-6, +1000E-6)),
174 h_vtx_y(new TH1D(
"",
";vtx_{y} (cm)", 100, -100E-3, +100E-3)),
175 h_chi_sq(new TH1D(
"",
";#chi^{2}", 100, 0., 10.)),
176 h_log_chi_sq(new TH1D(
"",
";log_{10} #chi^{2}", 100, -20., 5.)),
178 h_time(new TH1D(
"",
";time (ns)", 100, -2., +2.)),
179 h_time_unc(new TH1D(
"",
";time unc (ns)", 100, -1., +1.)),
184 h2_th_x_vs_xi(new TH2D(
"",
";#xi;#theta_{x} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
185 h2_th_y_vs_xi(new TH2D(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3, 100, -500E-6, +500E-6)),
186 h2_vtx_y_vs_xi(new TH2D(
"",
";#xi;vtx_{y} (cm)", 100, 0., 0.3, 100, -100E-3, +100E-3)),
187 p_th_x_vs_xi(new TProfile(
"",
";#xi;#theta_{x} (rad)", 100, 0., 0.3)),
188 p_th_y_vs_xi(new TProfile(
"",
";#xi;#theta_{y} (rad)", 100, 0., 0.3)),
189 p_vtx_y_vs_xi(new TProfile(
"",
";#xi;vtx_{y} (cm)", 100, 0., 0.3)),
191 new TH2D(
"",
";reco protons per event;timing tracks per event", 11, -0.5, 10.5, 11, -0.5, 10.5)),
192 h_xi_n1f1(new TH1D(
"",
";#xi", 100, 0., 0.3)),
195 new TH2D(
"",
";x_tracking (mm);x_timing (mm)", 100, 0., 20., 100, 0., 20.)),
202 new TH1D(
"",
";match between tracking and timing tracks", 2, -0.5, +1.5)),
207 std::vector<double> v_t_bin_edges;
208 for (
double t = 0;
t <= 5.;) {
209 v_t_bin_edges.push_back(
t);
210 const double de_t = 0.05 + 0.09 *
t + 0.02 *
t *
t;
213 h_t_unif = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", 100, 0., 5.);
214 h_t = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
215 h_t_xi_range1 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
216 h_t_xi_range2 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
217 h_t_xi_range3 = std::make_unique<TH1D>(
"",
";|t| (GeV^2)", v_t_bin_edges.size() - 1, v_t_bin_edges.data());
219 "",
";#xi;|t| (GeV^2)", 100, 0., 0.3, v_t_bin_edges.size() - 1, v_t_bin_edges.data());
221 for (
unsigned int n = 2;
n <= 10; ++
n)
229 unsigned int n_contrib_tracking_tracks = 0, n_contrib_timing_tracks = 0;
230 for (
const auto &tr :
p.contributingLocalTracks()) {
233 n_contrib_tracking_tracks++;
235 n_contrib_timing_tracks++;
238 const double th_x =
p.thetaX();
239 const double th_y =
p.thetaY();
240 const double mt = -
p.t();
259 if (
p.xi() > 0.04 &&
p.xi() < 0.07)
261 if (
p.xi() > 0.07 &&
p.xi() < 0.10)
263 if (
p.xi() > 0.10 &&
p.xi() < 0.13)
266 if (
p.timeError() > 0.) {
284 it->second->Fill(
p.xi());
307 auto g_th_x_RMS_vs_xi = std::make_unique<TGraphErrors>();
309 g_th_x_RMS_vs_xi->Write(
"g_th_x_RMS_vs_xi");
314 auto g_th_y_RMS_vs_xi = std::make_unique<TGraphErrors>();
316 g_th_y_RMS_vs_xi->Write(
"g_th_y_RMS_vs_xi");
321 auto g_vtx_y_RMS_vs_xi = std::make_unique<TGraphErrors>();
323 g_vtx_y_RMS_vs_xi->Write(
"g_vtx_y_RMS_vs_xi");
325 h_t->Scale(1.,
"width");
340 TDirectory *d_top = gDirectory;
342 gDirectory = d_top->mkdir(
"h_xi_nTracks");
345 sprintf(
buf,
"h_xi_nTracks_%u",
p.first);
346 p.second->Write(
buf);
381 :
h2_xi_mu_vs_xi_si(new TH2D(
"",
";#xi_{single};#xi_{multi}", 100, 0., 0.3, 100, 0., 0.3)),
382 h_xi_diff_mu_si(new TH1D(
"",
";#xi_{multi} - #xi_{single}", 100, -0.1, +0.1)),
383 h_xi_diff_si_mu(new TH1D(
"",
";#xi_{single} - #xi_{multi}", 100, -0.1, +0.1)),
385 new TH2D(
"",
";#xi_{multi};#xi_{single} - #xi_{multi}", 100, 0., 0.3, 100, -0.10, 0.10)),
388 new TH2D(
"",
";#theta^{*}_{y,si};#theta^{*}_{y,mu}", 100, -500E-6, +500E-6, 100, -500E-6, +500E-6)) {}
399 const double th_y_si = p_single.
thetaY();
400 const double th_y_mu = p_multi.
thetaY();
429 :
h_xi_si_diffNF(new TH1D(
"",
";#xi_{sF} - #xi_{sN}", 100, -0.02, +0.02)),
432 h_th_y_si_diffNF(new TH1D(
"",
";#theta_{y,sF} - #theta_{y,sN}", 100, -100E-6, +100E-6)),
439 const double th_y_s_N = p_s_N.
thetaY();
440 const double th_y_s_F = p_s_F.
thetaY();
477 tokenRecoProtonsSingleRP_(
479 tokenRecoProtonsMultiRP_(
484 rpId_45_N_(ps.getParameter<unsigned
int>(
"rpId_45_N")),
485 rpId_45_F_(ps.getParameter<unsigned
int>(
"rpId_45_F")),
486 rpId_56_N_(ps.getParameter<unsigned
int>(
"rpId_56_N")),
487 rpId_56_F_(ps.getParameter<unsigned
int>(
"rpId_56_F")),
489 outputFile_(ps.getParameter<
string>(
"outputFile")),
490 maxNonEmptyEvents_(ps.getUntrackedParameter<signed
int>(
"maxNonEmptyEvents", -1)),
492 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.)),
493 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.)),
495 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.)),
496 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.)),
498 n_non_empty_events_(0) {}
513 const double z_i =
geometry.rpTranslation(tr_i.rpId()).
z();
514 const double z_j =
geometry.rpTranslation(tr_j.rpId()).
z();
517 const double z_ti = -
geometry.rpTranslation(tr_ti.
rpId()).
z();
518 const double f_i = (z_ti - z_j) / (z_i - z_j), f_j = (z_i - z_ti) / (z_i - z_j);
519 const double x_inter = f_i * tr_i.x() + f_j * tr_j.x();
520 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();
526 de_x = tr_ti.
x() - x_inter;
527 de_x_unc =
sqrt(tr_ti.
xUnc() * tr_ti.
xUnc() + x_inter_unc_sq);
543 if (!hRecoProtonsSingleRP->empty())
547 throw cms::Exception(
"CTPPSProtonReconstructionPlotter") <<
"Number of non empty events reached maximum.";
558 std::map<unsigned int, unsigned int> armTrackCounter, armTimingTrackCounter;
559 std::map<unsigned int, unsigned int> armTrackCounter_N, armTrackCounter_F;
561 for (
const auto &tr : *hTracks) {
563 unsigned int decRPId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
567 armTrackCounter_N[0]++;
571 armTrackCounter_F[0]++;
575 armTrackCounter_N[1]++;
579 armTrackCounter_F[1]++;
582 armTrackCounter[rpId.arm()]++;
584 const bool trackerRP =
587 armTimingTrackCounter[rpId.arm()]++;
590 if (tr_L_N && tr_L_F) {
595 if (tr_R_N && tr_R_F) {
601 std::map<unsigned int, unsigned int> singleRPMultiplicity, multiRPMultiplicity;
604 multiRPMultiplicity[0] = multiRPMultiplicity[1] = 0;
607 for (
const auto &proton : *hRecoProtonsSingleRP) {
608 CTPPSDetId rpId((*proton.contributingLocalTracks().begin())->rpId());
609 unsigned int decRPId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
611 const bool n1f1 = (armTrackCounter_N[rpId.arm()] == 1 && armTrackCounter_F[rpId.arm()] == 1);
615 if (proton.validFit())
616 singleRPMultiplicity[
decRPId]++;
619 for (
const auto it : singleRPMultiplicity)
623 for (
const auto &proton : *hRecoProtonsMultiRP) {
624 CTPPSDetId rpId((*proton.contributingLocalTracks().begin())->rpId());
625 unsigned int armId = rpId.
arm();
627 const bool n1f1 = (armTrackCounter_N[armId] == 1 && armTrackCounter_F[armId] == 1);
629 multiRPPlots_[armId].fill(proton, armTrackCounter[armId], n1f1);
631 if (proton.validFit())
632 multiRPMultiplicity[armId]++;
635 for (
const auto it : multiRPMultiplicity) {
637 pl.h_multiplicity->Fill(
it.second);
638 pl.h2_timing_tracks_vs_prot_mult->Fill(
it.second, armTimingTrackCounter[
it.first]);
642 map<unsigned int, bool> clCo;
643 clCo[0] = (singleRPMultiplicity[
rpId_45_N_] && singleRPMultiplicity[
rpId_45_F_] && multiRPMultiplicity[0] == 1);
644 clCo[1] = (singleRPMultiplicity[
rpId_56_N_] && singleRPMultiplicity[
rpId_56_F_] && multiRPMultiplicity[1] == 1);
647 for (
const auto &proton : *hRecoProtonsMultiRP) {
648 if (!proton.validFit())
651 CTPPSDetId rpId_proton((*proton.contributingLocalTracks().begin())->rpId());
652 unsigned int armId = rpId_proton.
arm();
655 for (
const auto &tr : *hTracks) {
657 if (rpId_tr.arm() != armId)
660 const bool trackerRP =
665 double x_tr = -1., x_ti = -1.;
666 double de_x = 0., de_x_unc = 0.;
669 const double rd = (de_x_unc > 0.) ?
de_x / de_x_unc : -1E10;
671 const bool match = (ac.getTiTrMin() <= fabs(rd) && fabs(rd) <= ac.getTiTrMax());
673 pl.h_de_x_timing_vs_tracking->Fill(
de_x);
674 pl.h_de_x_rel_timing_vs_tracking->Fill(rd);
675 pl.h_de_x_match_timing_vs_tracking->Fill(
match ? 1. : 0.);
677 if (clCo[armId] && armTimingTrackCounter[armId] == 1) {
678 pl.h2_x_timing_vs_x_tracking_ClCo->Fill(x_tr, x_ti);
680 pl.h_de_x_timing_vs_tracking_ClCo->Fill(
de_x);
681 pl.h_de_x_rel_timing_vs_tracking_ClCo->Fill(rd);
682 pl.h_de_x_match_timing_vs_tracking_ClCo->Fill(
match ? 1. : 0.);
684 pl.p_time_unc_vs_x_ClCo->Fill(x_tr, proton.timeError());
690 for (
const auto &proton : *hRecoProtonsMultiRP) {
691 if (!proton.validFit())
694 CTPPSDetId rpId((*proton.contributingLocalTracks().begin())->rpId());
695 unsigned int armId = rpId.
arm();
697 const auto &nTimingTracks = armTimingTrackCounter[armId];
702 double x_ref = 0., y_ref = 0.;
712 if (nTimingTracks == 0)
713 pl.h2_y_vs_x_tt0_ClCo->Fill(x_ref, y_ref);
714 if (nTimingTracks == 1)
715 pl.h2_y_vs_x_tt1_ClCo->Fill(x_ref, y_ref);
716 if (nTimingTracks > 1)
717 pl.h2_y_vs_x_ttm_ClCo->Fill(x_ref, y_ref);
721 for (
const auto &proton_m : *hRecoProtonsMultiRP) {
722 CTPPSDetId rpId_m((*proton_m.contributingLocalTracks().begin())->rpId());
723 unsigned int arm = rpId_m.arm();
727 for (
const auto &proton_s : *hRecoProtonsSingleRP) {
730 bool compatible =
false;
731 for (
const auto &tr_m : proton_m.contributingLocalTracks()) {
732 if (tr_m.key() == key_s) {
742 CTPPSDetId rpId_s((*proton_s.contributingLocalTracks().begin())->rpId());
743 const unsigned int idx = rpId_s.arm() * 1000 + rpId_s.station() * 100 + rpId_s.rp() * 10 + rpId_s.arm();
747 const unsigned int rpDecId_s = rpId_s.arm() * 100 + rpId_s.station() * 10 + rpId_s.rp();
765 auto f_out = std::make_unique<TFile>(
outputFile_.c_str(),
"recreate");
773 TDirectory *d_singleRPPlots = f_out->mkdir(
"singleRPPlots");
775 gDirectory = d_singleRPPlots->mkdir(Form(
"rp%u",
it.first));
779 TDirectory *d_multiRPPlots = f_out->mkdir(
"multiRPPlots");
781 gDirectory = d_multiRPPlots->mkdir(Form(
"arm%u",
it.first));
785 TDirectory *d_singleMultiCorrelationPlots = f_out->mkdir(
"singleMultiCorrelationPlots");
787 unsigned int si_rp =
it.first / 10;
788 unsigned int mu_arm =
it.first % 10;
790 gDirectory = d_singleMultiCorrelationPlots->mkdir(Form(
"si_rp%u_mu_arm%u", si_rp, mu_arm));
794 TDirectory *d_armCorrelationPlots = f_out->mkdir(
"armCorrelationPlots");
796 gDirectory = d_armCorrelationPlots->mkdir(Form(
"arm%u",
it.first));
std::unique_ptr< TH2D > h2_timing_tracks_vs_prot_mult
static void profileToRMSGraph(TProfile *p, TGraphErrors *g)
std::unique_ptr< TH1D > h_th_y_si_diffNF
std::map< unsigned int, MultiRPPlots > multiRPPlots_
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsSingleRP_
std::unique_ptr< TProfile > p_th_y_vs_xi
std::unique_ptr< TProfile > p_time_unc_vs_x_ClCo
std::unique_ptr< TH2D > h2_xi_mu_vs_xi_si
const CTPPSLocalTrackLiteRefVector & contributingLocalTracks() const
list of RP tracks that contributed to this global track
std::unique_ptr< TProfile > p_y_R_diffNF_vs_y_R_N_
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
std::unique_ptr< TProfile > p_x_R_diffNF_vs_x_R_N_
std::map< unsigned int, SingleRPPlots > singleRPPlots_
Local (=single RP) track with essential information only.
std::unique_ptr< TH1D > h_xi_si_diffNF
std::unique_ptr< TH1D > h_xi_diff_si_mu
void analyze(const edm::Event &, const edm::EventSetup &) override
signed int n_non_empty_events_
float thetaY() const
horizontal scattering angle, in rad
std::unique_ptr< TH1D > h_xi_n1f1
edm::ESGetToken< PPSAssociationCuts, PPSAssociationCutsRcd > ppsAssociationCutsToken_
std::unique_ptr< TProfile > p_y_L_diffNF_vs_y_L_N_
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geometryESToken_
edm::EDGetTokenT< CTPPSLocalTrackLiteCollection > tokenTracks_
std::unique_ptr< TH2D > h2_th_y_vs_xi
std::unique_ptr< TH1D > h_t_unif
std::unique_ptr< TProfile > p_th_y_si_diffNF_vs_xi_mu
std::unique_ptr< TH1D > h_chi_sq
value_type const at(size_type idx) const
Retrieve an element of the RefVector.
float y() const
returns the vertical track position
std::unique_ptr< TH1D > h_vtx_y
std::unique_ptr< TH1D > h_n_contrib_tracking_tracks
void fill(const reco::ForwardProton &p_single, const reco::ForwardProton &p_multi)
std::unique_ptr< TH2D > h2_xi_si_diffNF_vs_xi_mu
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
std::map< unsigned int, TH1D * > m_h_xi_nTracks
const CutsPerArm & getAssociationCuts(const int sector) const
std::unique_ptr< TH1D > h_t_xi_range3
std::unique_ptr< TH1D > h_t_xi_range2
std::unique_ptr< TH1D > h_de_x_match_timing_vs_tracking_ClCo
std::unique_ptr< TH1D > h_xi
std::unique_ptr< TProfile > p_vtx_y_vs_xi
std::unique_ptr< TH2D > h2_th_x_vs_xi
float x() const
returns the horizontal track position
std::unique_ptr< TProfile > p_time_unc_vs_xi
std::unique_ptr< TH2D > h2_t_vs_xi
std::unique_ptr< TH2D > h2_xi_diff_si_mu_vs_xi_mu
std::unique_ptr< TH2D > h2_y_vs_x_tt0_ClCo
std::unique_ptr< TProfile > p_th_y_vs_xi
std::unique_ptr< TH1D > h_log_chi_sq
#define DEFINE_FWK_MODULE(type)
std::unique_ptr< TH1D > h_t
float xi() const
longitudinal fractional momentum loss
std::unique_ptr< TH1D > h_de_x_timing_vs_tracking_ClCo
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
std::unique_ptr< TH2D > h2_th_y_mu_vs_th_y_si
std::unique_ptr< TH2D > h2_th_y_vs_xi
std::map< unsigned int, ArmCorrelationPlots > armCorrelationPlots_
The manager class for TOTEM RP geometry.
std::unique_ptr< TH1D > h_multiplicity
std::unique_ptr< TH1D > h_time
Log< level::Info, false > LogInfo
std::unique_ptr< TH1D > h_th_y
SingleMultiCorrelationPlots()
std::unique_ptr< TH1D > h_th_x
std::unique_ptr< TH1D > h_de_x_rel_timing_vs_tracking
std::unique_ptr< TH1D > h_de_x_timing_vs_tracking
bool validFit() const
flag for the fit validity
std::unique_ptr< TProfile > p_xi_diff_si_mu_vs_xi_mu
std::vector< CTPPSLocalTrackLite > CTPPSLocalTrackLiteCollection
Collection of CTPPSLocalTrackLite objects.
std::unique_ptr< TH1D > h_xi_diff_mu_si
std::unique_ptr< TH1D > h_t_xi_range1
std::unique_ptr< TH2D > h2_vtx_y_vs_xi
~CTPPSProtonReconstructionPlotter() override
std::unique_ptr< TH2D > h2_y_vs_x_tt1_ClCo
Base class for CTPPS detector IDs.
signed int maxNonEmptyEvents_
void CalculateTimingTrackingDistance(const reco::ForwardProton &proton, const CTPPSLocalTrackLite &tr, const CTPPSGeometry &geometry, double &x_tr, double &x_ti, double &de_x, double &de_x_unc)
float xUnc() const
returns the horizontal track position uncertainty
std::unique_ptr< TH1D > h_de_x_rel_timing_vs_tracking_ClCo
CTPPSProtonReconstructionPlotter(const edm::ParameterSet &)
std::unique_ptr< TH1D > h_xi
std::unique_ptr< TH2D > h2_y_vs_x_ttm_ClCo
std::unique_ptr< TH1D > h_de_x_match_timing_vs_tracking
std::map< unsigned int, SingleMultiCorrelationPlots > singleMultiCorrelationPlots_
std::map< unsigned int, TH1D * > m_h_xi_nTracks
std::unique_ptr< TH2D > h2_x_timing_vs_x_tracking_ClCo
std::unique_ptr< TH1D > h_n_contrib_timing_tracks
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
uint32_t rpId() const
returns the RP id
std::vector< ForwardProton > ForwardProtonCollection
Collection of ForwardProton objects.
std::unique_ptr< TH1D > h_time_unc
void fill(const reco::ForwardProton &p_s_N, const reco::ForwardProton &p_s_F, const reco::ForwardProton &p_m)
std::unique_ptr< TH1D > h_xi_n1f1
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
std::unique_ptr< TH1D > h_multiplicity
std::unique_ptr< TProfile > p_th_x_vs_xi
std::unique_ptr< TProfile > p_x_L_diffNF_vs_x_L_N_
std::unique_ptr< TH1D > h_chi_sq_norm
void fill(const reco::ForwardProton &p, unsigned int nTracks, bool n1f1)
std::unique_ptr< TProfile > p_xi_si_diffNF_vs_xi_mu
void fill(const reco::ForwardProton &p, unsigned int nTracks, bool n1f1)