2525#include " Framework/runDataProcessing.h"
2626
2727#include < map>
28+ #include < memory>
29+ #include < string>
2830#include < vector>
2931
3032using namespace o2 ;
3133using namespace o2 ::framework;
34+ std::shared_ptr<TH1> particlePdgCodes;
35+ std::map<int , std::shared_ptr<TH1>> particlePtDistribution;
36+ std::map<int , std::shared_ptr<TH1>> particleEtaDistribution;
37+ std::map<int , std::shared_ptr<TH1>> ptDistribution;
3238std::map<int , std::shared_ptr<TH2>> ptResolutionVsPt;
3339std::map<int , std::shared_ptr<TH2>> invPtResolutionVsPt;
3440std::map<int , std::shared_ptr<TH2>> dcaXyResolutionVsPt;
3541std::map<int , std::shared_ptr<TH2>> dcaZResolutionVsPt;
3642
37- struct alice3TrackingPerformance {
38- Configurable<std::vector<int >> pdgCodes{" pdgCodes" , {211 }, " List of PDG codes to consider for efficiency calculation" };
43+ struct Alice3TrackingPerformance {
44+ Configurable<std::vector<int >> pdgCodes{" pdgCodes" , {0 , 211 }, " List of PDG codes to consider for efficiency calculation. (0 means all) " };
3945 HistogramRegistry histos{" Histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
4046 Configurable<std::pair<float , float >> etaRange{" etaRange" , {-5 .f , 5 .f }, " Eta range for efficiency calculation" };
4147
4248 void init (o2::framework::InitContext&)
4349 {
4450 const AxisSpec axisPt{100 , 0 , 10 , " p_{T} (GeV/c)" };
51+ const AxisSpec axisEta{100 , etaRange.value .first , etaRange.value .second , " #eta" };
4552 const AxisSpec axisPtDelta{100 , -1 , 1 , " p_{T}^{gen} - p_{T}^{reco} (GeV/c)" };
4653 const AxisSpec axisInvPtDelta{100 , -1 , 1 , " 1./p_{T}^{gen} - 1./p_{T}^{reco} (GeV/c)^{-1}" };
4754 const AxisSpec axisDcaXy{100 , -1 , 1 , " DCA_{xy} (cm)" };
4855 const AxisSpec axisDcaZ{100 , -1 , 1 , " DCA_{z} (cm)" };
49- for (auto pdg : pdgCodes.value ) {
50- ptResolutionVsPt[pdg] = histos.add <TH2>(Form (" ptResolutionVsPt_%d" , pdg), " " , kTH2D , {axisPt, axisPtDelta});
51- invPtResolutionVsPt[pdg] = histos.add <TH2>(Form (" invPtResolutionVsPt_%d" , pdg), " " , kTH2D , {axisPt, axisInvPtDelta});
52- dcaXyResolutionVsPt[pdg] = histos.add <TH2>(Form (" dcaXyResolutionVsPt_%d" , pdg), " " , kTH2D , {axisPt, axisDcaXy});
53- dcaZResolutionVsPt[pdg] = histos.add <TH2>(Form (" dcaZResolutionVsPt_%d" , pdg), " " , kTH2D , {axisPt, axisDcaZ});
56+ particlePdgCodes = histos.add <TH1>(" particlePdgCodes" , " " , kTH1D , {AxisSpec{100 , -0.5 , 99.5 , " PDG Code" }});
57+ for (const int & pdg : pdgCodes.value ) {
58+ std::string tag = Form (" _%d" , pdg);
59+ if (pdg < 0 ) {
60+ tag = Form (" _m%d" , -pdg);
61+ }
62+ particlePtDistribution[pdg] = histos.add <TH1>(" particlePtDistribution" + tag, " " , kTH1D , {axisPt});
63+ particleEtaDistribution[pdg] = histos.add <TH1>(" particleEtaDistribution" + tag, " " , kTH1D , {axisEta});
64+
65+ ptDistribution[pdg] = histos.add <TH1>(" ptDistribution" + tag, " " , kTH1D , {axisPt});
66+ ptResolutionVsPt[pdg] = histos.add <TH2>(" ptResolutionVsPt" + tag, " " , kTH2D , {axisPt, axisPtDelta});
67+ invPtResolutionVsPt[pdg] = histos.add <TH2>(" invPtResolutionVsPt" + tag, " " , kTH2D , {axisPt, axisInvPtDelta});
68+ dcaXyResolutionVsPt[pdg] = histos.add <TH2>(" dcaXyResolutionVsPt" + tag, " " , kTH2D , {axisPt, axisDcaXy});
69+ dcaZResolutionVsPt[pdg] = histos.add <TH2>(" dcaZResolutionVsPt" + tag, " " , kTH2D , {axisPt, axisDcaZ});
5470 }
5571 }
5672
5773 void process (soa::Join<aod::Tracks, o2::aod::McTrackLabels, o2::aod::TracksDCA> const & tracks,
58- aod::McParticles const &)
74+ aod::McParticles const & mcParticles )
5975 {
6076 auto isParticleSelected = [&](const o2::aod::McParticle& p) {
6177 if (!p.isPhysicalPrimary ()) {
@@ -69,17 +85,37 @@ struct alice3TrackingPerformance {
6985 }
7086 return true ;
7187 };
88+
89+ for (const auto & mcParticle : mcParticles) {
90+ particlePdgCodes->Fill (Form (" %d" , mcParticle.pdgCode ()), 1 );
91+ if (!isParticleSelected (mcParticle)) {
92+ continue ;
93+ }
94+ particlePtDistribution[0 ]->Fill (mcParticle.pt ());
95+ particleEtaDistribution[0 ]->Fill (mcParticle.eta ());
96+ if (particlePtDistribution.find (mcParticle.pdgCode ()) == particlePtDistribution.end ()) {
97+ continue ;
98+ }
99+ particlePtDistribution[mcParticle.pdgCode ()]->Fill (mcParticle.pt ());
100+ particleEtaDistribution[mcParticle.pdgCode ()]->Fill (mcParticle.eta ());
101+ }
72102 for (const auto & track : tracks) {
103+ ptDistribution[0 ]->Fill (track.pt ());
73104 if (!track.has_mcParticle ()) {
74105 continue ;
75106 }
76107 const auto & mcParticle = track.mcParticle ();
108+ ptResolutionVsPt[0 ]->Fill (mcParticle.pt (), mcParticle.pt () - track.pt ());
109+ invPtResolutionVsPt[0 ]->Fill (mcParticle.pt (), 1 .f / mcParticle.pt () - 1 .f / track.pt ());
110+ dcaXyResolutionVsPt[0 ]->Fill (mcParticle.pt (), track.dcaXY ());
111+ dcaZResolutionVsPt[0 ]->Fill (mcParticle.pt (), track.dcaZ ());
77112 if (!isParticleSelected (mcParticle)) {
78113 continue ;
79114 }
80115 if (ptResolutionVsPt.find (mcParticle.pdgCode ()) == ptResolutionVsPt.end ()) {
81116 continue ;
82117 }
118+ ptDistribution[mcParticle.pdgCode ()]->Fill (mcParticle.pt ());
83119 ptResolutionVsPt[mcParticle.pdgCode ()]->Fill (mcParticle.pt (), mcParticle.pt () - track.pt ());
84120 invPtResolutionVsPt[mcParticle.pdgCode ()]->Fill (mcParticle.pt (), 1 .f / mcParticle.pt () - 1 .f / track.pt ());
85121 dcaXyResolutionVsPt[mcParticle.pdgCode ()]->Fill (mcParticle.pt (), track.dcaXY ());
@@ -90,5 +126,5 @@ struct alice3TrackingPerformance {
90126
91127WorkflowSpec defineDataProcessing (ConfigContext const & ctx)
92128{
93- return WorkflowSpec{adaptAnalysisTask<alice3TrackingPerformance >(ctx)};
129+ return WorkflowSpec{adaptAnalysisTask<Alice3TrackingPerformance >(ctx)};
94130}
0 commit comments