2424
2525using namespace o2 ;
2626using namespace o2 ::analysis;
27+ using namespace o2 ::constants::math;
2728using namespace o2 ::framework;
2829using namespace o2 ::framework::expressions;
2930
@@ -33,10 +34,40 @@ enum Channel : uint8_t {
3334 NChannels
3435};
3536
37+ namespace o2 ::aod
38+ {
39+ namespace hf_charm_cand_lite
40+ {
41+ DECLARE_SOA_COLUMN (M, m, float ); // ! Invariant mass of candidate (GeV/c2)
42+ DECLARE_SOA_COLUMN (Pt, pt, float ); // ! Transverse momentum of candidate (GeV/c)
43+ DECLARE_SOA_COLUMN (Y, y, float ); // ! Rapidity of candidate
44+ DECLARE_SOA_COLUMN (Eta, eta, float ); // ! Pseudorapidity of candidate
45+ DECLARE_SOA_COLUMN (Phi, phi, float ); // ! Azimuth angle of candidate
46+ DECLARE_SOA_COLUMN (MlScoreBkg, mlScoreBkg, float ); // ! ML score for background class
47+ DECLARE_SOA_COLUMN (MlScorePrompt, mlScorePrompt, float ); // ! ML Prompt score for prompt class
48+ DECLARE_SOA_COLUMN (MlScoreNonPrompt, mlScoreNonPrompt, float ); // ! ML Non Prompt score for non prompt class
49+ }
50+
51+ DECLARE_SOA_TABLE (HfCharmCandLites, " AOD" , " HFCHARMCANDLITE" , // ! Table with some B+ properties
52+ hf_charm_cand_lite::M,
53+ hf_charm_cand_lite::Pt,
54+ hf_charm_cand_lite::Y,
55+ hf_charm_cand_lite::Eta,
56+ hf_charm_cand_lite::Phi,
57+ hf_charm_cand_lite::MlScoreBkg,
58+ hf_charm_cand_lite::MlScorePrompt,
59+ hf_charm_cand_lite::MlScoreNonPrompt);
60+ }
61+
3662struct HfTaskCharmHadImpactPar {
63+ Produces<aod::HfCharmCandLites> hfCharmCandLite;
64+
3765 Configurable<int > selectionFlag{" selectionFlag" , 15 , " Selection Flag for the considered charm hadron" };
66+ Configurable<int > fillLightTreeCandidate{" fillLightTreeCandidate" , 0 , " Flag to store charm hadron features" };
3867 ConfigurableAxis axisPt{" axisPt" , {0 .f , 1 .f , 2 .f , 3 .f , 4 .f , 5 .f , 6 .f , 8 .f , 10 .f , 12 .f , 16 .f , 24 .f , 36 .f , 50 .f }, " axis for pT of charm hadron" };
3968 ConfigurableAxis axisMass{" axisMass" , {250 , 1 .65f , 2 .15f }, " axis for mass of charm hadron" };
69+ ConfigurableAxis axisPhi{" axisPhi" , {100 , 0 .f , 2 *PI}, " axis for azimuthal angle of charm hadron" };
70+ ConfigurableAxis axisEta{" axisEta" , {100 , -2 .f , 2 .f }, " axis for pseudorapidity of charm hadron" };
4071 ConfigurableAxis axisImpPar{" axisImpPar" , {2000 , -500 .f , 500 .f }, " axis for impact-parameter of charm hadron" };
4172 ConfigurableAxis axisMlScore0{" axisMlScore0" , {100 , 0 .f , 1 .f }, " axis for ML output score 0" };
4273 ConfigurableAxis axisMlScore1{" axisMlScore1" , {100 , 0 .f , 1 .f }, " axis for ML output score 1" };
@@ -62,8 +93,10 @@ struct HfTaskCharmHadImpactPar {
6293 }
6394 if (doprocessDplus || doprocessDzero) {
6495 registry.add (" hMassPtImpPar" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c});dca XY (#mum);" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar});
96+ registry.add (" hMassPtPhiEta" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c}); phi; eta;" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar, axisPhi, axisEta});
6597 } else if (doprocessDplusWithMl || doprocessDzeroWithMl) {
6698 registry.add (" hMassPtImpPar" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c});dca XY (#mum);ML score 0;ML score 1; ML score 2;" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar, axisMlScore0, axisMlScore1, axisMlScore2});
99+ registry.add (" hMassPtPhiEta" , " ;#it{M} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c}); phi; eta; ML score 0;ML score 1; ML score 2;" , HistType::kTHnSparseF , {axisMass, axisPt, axisImpPar, axisPhi, axisEta, axisMlScore0, axisMlScore1, axisMlScore2});
67100 }
68101 }
69102
@@ -81,8 +114,10 @@ struct HfTaskCharmHadImpactPar {
81114 outputMl[iScore] = candidate.mlProbDplusToPiKPi ()[iScore];
82115 }
83116 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
117+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
84118 } else {
85119 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY ());
120+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta ());
86121 }
87122 } else if constexpr (channel == Channel::DzeroToKPi) {
88123 if (candidate.isSelD0 ()) { // D0 -> Kpi
@@ -92,8 +127,10 @@ struct HfTaskCharmHadImpactPar {
92127 outputMl[iScore] = candidate.mlProbD0 ()[iScore];
93128 }
94129 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
130+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
95131 } else {
96132 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY ());
133+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta ());
97134 }
98135 }
99136 if (candidate.isSelD0bar ()) {
@@ -103,19 +140,72 @@ struct HfTaskCharmHadImpactPar {
103140 outputMl[iScore] = candidate.mlProbD0bar ()[iScore];
104141 }
105142 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
143+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
106144 } else {
107145 registry.fill (HIST (" hMassPtImpPar" ), invMass, candidate.pt (), candidate.impactParameterXY ());
146+ registry.fill (HIST (" hMassPtPhiEta" ), invMass, candidate.pt (), candidate.phi (), candidate.eta (), outputMl[0 ], outputMl[1 ], outputMl[2 ]);
108147 }
109148 }
110149 }
111150 }
112151
152+ // Fill THnSparses for the ML analysis
153+ // / \param candidate is a particle candidate
154+ template <Channel channel, bool withMl, typename CCands>
155+ void fillTree (const CCands& candidate)
156+ {
157+ std::vector<float > outputMl = {-999 ., -999 ., -999 .};
158+ float invMass{-1 .f };
159+ float yCand{-999 .f };
160+ if constexpr (channel == Channel::DplusToKPiPi) { // D+ -> Kpipi
161+ invMass = hfHelper.invMassDplusToPiKPi (candidate);
162+ yCand = hfHelper.yDplus (candidate);
163+ if constexpr (withMl) {
164+ for (auto iScore{0u }; iScore < candidate.mlProbDplusToPiKPi ().size (); ++iScore) {
165+ outputMl[iScore] = candidate.mlProbDplusToPiKPi ()[iScore];
166+ }
167+ }
168+ } else if constexpr (channel == Channel::DzeroToKPi) {
169+ if (candidate.isSelD0 ()) { // D0 -> Kpi
170+ invMass = hfHelper.invMassD0ToPiK (candidate);
171+ yCand = hfHelper.yD0 (candidate);
172+ if constexpr (withMl) {
173+ for (auto iScore{0u }; iScore < candidate.mlProbD0 ().size (); ++iScore) {
174+ outputMl[iScore] = candidate.mlProbD0 ()[iScore];
175+ }
176+ }
177+ }
178+ if (candidate.isSelD0bar ()) {
179+ invMass = hfHelper.invMassD0barToKPi (candidate);
180+ yCand = hfHelper.yD0 (candidate);
181+ if constexpr (withMl) {
182+ for (auto iScore{0u }; iScore < candidate.mlProbD0bar ().size (); ++iScore) {
183+ outputMl[iScore] = candidate.mlProbD0bar ()[iScore];
184+ }
185+ }
186+ }
187+ }
188+ hfCharmCandLite (
189+ // Charm candidate meson features
190+ invMass,
191+ candidate.pt (),
192+ yCand,
193+ candidate.eta (),
194+ candidate.phi (),
195+ outputMl[0 ],
196+ outputMl[1 ],
197+ outputMl[2 ]);
198+ }
199+
113200 // / \param candidates are reconstructed candidates
114201 template <Channel channel, bool withMl, typename CCands>
115202 void runAnalysis (const CCands& candidates)
116203 {
117204 for (auto const & candidate : candidates) {
118205 fillSparse<channel, withMl>(candidate);
206+ if (fillLightTreeCandidate){
207+ fillTree<channel, withMl>(candidate);
208+ }
119209 }
120210 }
121211
0 commit comments