3838#include < tuple>
3939#include < vector>
4040
41+ // #include "Framework/Logger.h"
42+
4143using namespace o2 ;
4244using namespace o2 ::framework;
4345using namespace o2 ::ml;
@@ -64,6 +66,7 @@ struct ParticleCompositionCorrection {
6466
6567 Configurable<bool > skipAll{" skipAll" , false , " run table producer in dummy mode, i.e. skip all computations and fill with 1" };
6668 Configurable<bool > skipSec{" skipSec" , false , " dont calculate weights for secondaries" };
69+ Configurable<bool > skipNeutralSec{" skipNeutralSec" , true , " dont calculate weights for neutral secondaries" };
6770 Configurable<bool > skipNonPhysicalPrim{" skipNonPhysicalPrim" , true , " dont calculate weights for particles that are not (originating from) physical primaries; i.e. reject (decays of) pi0 etc." };
6871 Configurable<float > etaCut{" etaCut" , 0 .8f , " eta cut" };
6972 Configurable<float > ptMinCut{" ptMinCut" , 0 .15f , " pt min cut" };
@@ -118,6 +121,7 @@ void ParticleCompositionCorrection::init(InitContext const&)
118121 const int maxMult = 100 ;
119122 const int nBinsMult = maxMult + 1 ;
120123 const AxisSpec multAxis = {nBinsMult, -0.5 , nBinsMult - 0.5 , " #it{N}_{ch}" , " mult" };
124+ const AxisSpec processAxis = {51 , -0.5 , 50.5 , " process" , " process" };
121125
122126 histos.add (" multDist_INELg0" , " " , kTH1D , {multAxis});
123127 histos.add (" multDist_fid" , " " , kTH1D , {multAxis});
@@ -127,47 +131,64 @@ void ParticleCompositionCorrection::init(InitContext const&)
127131 histos.add (" frac/data/proton" , " " , kTProfile , {ptAxis});
128132 histos.add (" frac/data/sigma" , " " , kTProfile , {ptAxis});
129133
130- histos.add (" frac/data/kaon_mult" , " " , kTProfile2D , {multAxis, ptAxis});
131- histos.add (" frac/data/proton_mult" , " " , kTProfile2D , {multAxis, ptAxis});
132- histos.add (" frac/data/sigma_mult" , " " , kTProfile2D , {multAxis, ptAxis});
133-
134134 histos.addClone (" frac/data/" , " frac/mc/" );
135135
136136 histos.add (" weight/kaon" , " " , kTProfile , {ptAxis});
137137 histos.add (" weight/proton" , " " , kTProfile , {ptAxis});
138138 histos.add (" weight/sigma" , " " , kTProfile , {ptAxis});
139139
140- histos.add (" weight/kaon_mult" , " " , kTProfile2D , {multAxis, ptAxis});
141- histos.add (" weight/proton_mult" , " " , kTProfile2D , {multAxis, ptAxis});
142- histos.add (" weight/sigma_mult" , " " , kTProfile2D , {multAxis, ptAxis});
143-
140+ histos.add (" weight/prim" , " " , kTProfile , {ptAxis});
144141 histos.add (" weight/secDec" , " " , kTProfile , {ptAxis});
145142 histos.add (" weight/secMat" , " " , kTProfile , {ptAxis});
146-
147- histos.add (" weight/secDec_mult" , " " , kTProfile2D , {multAxis, ptAxis});
148- histos.add (" weight/secMat_mult" , " " , kTProfile2D , {multAxis, ptAxis});
149143 }
150144}
151145
152146std::tuple<float , float , float > ParticleCompositionCorrection::getWeights (aod::McParticles const & particles, aod::McParticles::iterator const & particle, std::map<int32_t , std::tuple<float , float , float >>& storedWeights, float dNdEta)
153147{
154148 static const std::tuple<float , float , float > noWeights = {1 .f , 1 .f , 1 .f };
155149
156- if (skipAll || std::abs (particle.eta ()) > etaCut || particle.pt () < ptMinCut || particle.pt () > ptMaxCut) {
150+ static constexpr int kXi0PDG = 3322 ;
151+
152+ /* if (skipAll || std::abs(particle.eta()) > etaCut || particle.pt() < ptMinCut || particle.pt() > ptMaxCut) {
153+ return noWeights;
154+ } */
155+
156+ if (skipAll) {
157157 return noWeights;
158158 }
159159
160- if (particle.producedByGenerator ()) {
161- if (skipNonPhysicalPrim && !particle.isPhysicalPrimary ()) {
162- return noWeights;
163- }
160+ if (!particle.has_mothers ()) {
161+ return noWeights;
162+ }
163+
164+ auto particleMother = particle.mothersIds ()[0 ] - particles.offset ();
165+
166+ // if (particle.producedByGenerator()) {
167+
168+ if (particleMother == 0 . || particleMother == 1 . ||
169+ (particle.isPhysicalPrimary () && skipNonPhysicalPrim)) {
170+
164171 auto absPDGCode = std::abs (particle.pdgCode ());
165- // translate abs PDG code to PID variable of neural networks (0: pion, 1: kaon, 2: proton, 3: sigma)
166172
167173 if (absPDGCode == PDG_t::kPiPlus || absPDGCode == PDG_t::kPi0 ) {
174+
175+ return noWeights;
176+ }
177+
178+ if (skipNonPhysicalPrim && !particle.isPhysicalPrimary ()) {
168179 return noWeights;
169180 }
170181
182+ if (!particle.has_daughters ()) {
183+
184+ if (particle.eta () > etaCut || particle.pt () > ptMaxCut || particle.pt () < ptMinCut) {
185+
186+ return noWeights;
187+ }
188+ }
189+
190+ // translate abs PDG code to PID variable of neural networks (0: pion, 1: kaon, 2: proton, 3: sigma)
191+
171192 static const std::map<int , float > mapPID = {
172193 {PDG_t::kPiPlus , 0 .f },
173194 {PDG_t::kPi0 , 0 .f },
@@ -181,79 +202,106 @@ std::tuple<float, float, float> ParticleCompositionCorrection::getWeights(aod::M
181202 {PDG_t::kLambda0 , 3 .f },
182203 {PDG_t::kSigma0 , 3 .f },
183204 {PDG_t::kXiMinus , 3 .f },
184- // TODO: potentially extend by xi0/eta/omega/rho/phi/Delta...
205+ {kXi0PDG , 3 .f }, // Xi0
206+ {PDG_t::kOmegaMinus , 3 .f },
207+ // TODO: potentially extend by eta/omega/rho/phi/Delta...
185208 // pdg codes defined in AliceO2/Common/Constants/include/CommonConstants/PhysicsConstants.h
186209 // e.g. o2::constants::physics::Pdg::kEta
187210 };
188211
189212 if (auto iterMapPID = mapPID.find (absPDGCode); iterMapPID != mapPID.end ()) {
190- // LOGP(info, "scaling a {} with status code {} from process {}", particle.pdgCode(), particle.getGenStatusCode(), particle.getProcess());
191- float pt = particle.pt ();
192213
193214 // calculate particle fractions and corresponding weight for given reference particle
194- std::vector<std::vector<float >> input = {{dNdEta}, {pt }, {iterMapPID->second }};
215+ std::vector<std::vector<float >> input = {{dNdEta}, {particle. pt () }, {iterMapPID->second }};
195216 float fracData = particleFractionsData.evalModel (input)[0 ];
196217 float fracMC = particleFractionsMC.evalModel (input)[0 ];
197218 float weight = (fracMC) ? fracData / fracMC : 1 .f ;
198219 std::tuple<float , float , float > weights = {weight, weight, weight};
199220 if (!skipSec && particle.has_daughters ()) {
200221 storedWeights[particle.index ()] = weights;
201222 }
202- if (enableQAHistos && particle.isPhysicalPrimary () && std::abs (particle.eta ()) < 0.8 ) { // o2-linter: disable=magic-number (usual range of charged-partilce measurements)
223+ if (enableQAHistos && particle.isPhysicalPrimary () && std::abs (particle.eta ()) < etaCut ) {
203224 if (iterMapPID->first == PDG_t::kKPlus ) {
204- histos.fill (HIST (" frac/data/kaon" ), pt, fracData);
205- histos.fill (HIST (" frac/mc/kaon" ), pt, fracMC);
206- histos.fill (HIST (" frac/data/kaon_mult" ), dNdEta, pt, fracData);
207- histos.fill (HIST (" frac/mc/kaon_mult" ), dNdEta, pt, fracMC);
208- histos.fill (HIST (" weight/kaon" ), pt, weight);
209- histos.fill (HIST (" weight/kaon_mult" ), dNdEta, pt, weight);
225+ histos.fill (HIST (" frac/data/kaon" ), particle.pt (), fracData);
226+ histos.fill (HIST (" frac/mc/kaon" ), particle.pt (), fracMC);
227+ histos.fill (HIST (" weight/kaon" ), particle.pt (), weight);
210228 }
211229 if (iterMapPID->first == PDG_t::kProton ) {
212- histos.fill (HIST (" frac/data/proton" ), pt, fracData);
213- histos.fill (HIST (" frac/mc/proton" ), pt, fracMC);
214- histos.fill (HIST (" frac/data/proton_mult" ), dNdEta, pt, fracData);
215- histos.fill (HIST (" frac/mc/proton_mult" ), dNdEta, pt, fracMC);
216- histos.fill (HIST (" weight/proton" ), pt, weight);
217- histos.fill (HIST (" weight/proton_mult" ), dNdEta, pt, weight);
230+ histos.fill (HIST (" frac/data/proton" ), particle.pt (), fracData);
231+ histos.fill (HIST (" frac/mc/proton" ), particle.pt (), fracMC);
232+ histos.fill (HIST (" weight/proton" ), particle.pt (), weight);
218233 }
219234 if (iterMapPID->first == PDG_t::kSigmaPlus || iterMapPID->first == PDG_t::kSigmaMinus ) {
220- histos.fill (HIST (" frac/data/sigma" ), pt, fracData);
221- histos.fill (HIST (" frac/mc/sigma" ), pt, fracMC);
222- histos.fill (HIST (" frac/data/sigma_mult" ), dNdEta, pt, fracData);
223- histos.fill (HIST (" frac/mc/sigma_mult" ), dNdEta, pt, fracMC);
224- histos.fill (HIST (" weight/sigma" ), pt, weight);
225- histos.fill (HIST (" weight/sigma_mult" ), dNdEta, pt, weight);
235+ histos.fill (HIST (" frac/data/sigma" ), particle.pt (), fracData);
236+ histos.fill (HIST (" frac/mc/sigma" ), particle.pt (), fracMC);
237+ histos.fill (HIST (" weight/sigma" ), particle.pt (), weight);
226238 }
239+
240+ histos.fill (HIST (" weight/prim" ), particle.pt (), weight);
227241 }
242+
228243 return weights;
229244 }
245+
230246 } else if (!skipSec) {
247+
231248 auto refParticleID = particle.index ();
232- // LOGP(error, "Particle [{}] {} from process {}", refParticleID, particle.pdgCode(), particle.getProcess());
233- while (!particles.iteratorAt (refParticleID).producedByGenerator () && particles.iteratorAt (refParticleID).has_mothers ()) {
249+ auto pdgParticle = pdg->GetParticle (particle.pdgCode ());
250+
251+ if (!pdgParticle) {
252+ // LOGP(info, "Unknown PDG code: {}", particle.pdgCode());
253+ // return noWeights;
254+ } else {
255+
256+ if (skipNeutralSec && pdgParticle->Charge () == 0 .) {
257+ return noWeights;
258+ }
259+ }
260+
261+ if (particle.eta () > etaCut || particle.pt () > ptMaxCut || particle.pt () < ptMinCut) {
262+ return noWeights;
263+ }
264+
265+ while (particles.iteratorAt (refParticleID).has_mothers ()) {
266+
234267 auto motherID = particles.iteratorAt (refParticleID).mothersIds ()[0 ] - particles.offset ();
235- // LOGP(error, "-> mom [{}] {} from process {}", motherID, particles.iteratorAt(motherID).pdgCode(), particles.iteratorAt(motherID).getProcess());
268+
269+ auto mom = particles.iteratorAt (motherID);
270+
271+ if (!mom.has_mothers ()) {
272+ break ;
273+ }
274+
236275 refParticleID = motherID;
276+
277+ if (mom.isPhysicalPrimary () && skipNonPhysicalPrim) {
278+ break ;
279+ }
280+ }
281+
282+ if (refParticleID == 0 || refParticleID == 1 ) {
283+ LOGF (error, " GLOBAL MOTHER IS INCIDING PROTON" );
237284 }
238285
239286 if (storedWeights.find (refParticleID) == storedWeights.end ()) {
240- // LOGP(error , " no ref particle stored for particle {} from process {}!!", particle.pdgCode(), particle.getProcess ());
287+ // LOGP(info , "MCB: no ref stored for mom {}, PDG: {}!!", particles.iteratorAt(refParticleID).index(),particles.iteratorAt(refParticleID).pdgCode ());
241288 return noWeights;
242289 }
243290
244291 if (enableQAHistos) {
292+
245293 float weight = get<0 >(storedWeights.at (refParticleID));
246- auto pdgParticle = pdg-> GetParticle (particle. pdgCode ());
294+
247295 if (pdgParticle && pdgParticle->Charge () != 0 .) {
248- if (particle.getProcess () == TMCProcess::kPDecay ) {
296+ if (particle.getProcess () == TMCProcess::kPDecay || particle. getProcess () == TMCProcess:: kPPrimary ) {
249297 histos.fill (HIST (" weight/secDec" ), particle.pt (), weight);
250- histos. fill ( HIST ( " weight/secDec_mult " ), dNdEta, particle.pt (), weight);
251- } else if (particle. getProcess () == TMCProcess:: kPHInhelastic || particle. getProcess () == TMCProcess:: kPHadronic || particle. getProcess () == TMCProcess:: kPHElastic ) {
298+ // } else if (particle.getProcess() == TMCProcess::kPHInhelastic || particle.getProcess() == TMCProcess::kPHadronic || particle.getProcess() == TMCProcess::kPHElastic) {
299+ } else {
252300 histos.fill (HIST (" weight/secMat" ), particle.pt (), weight);
253- histos.fill (HIST (" weight/secMat_mult" ), dNdEta, particle.pt (), weight);
254301 }
255302 }
256303 }
304+
257305 return storedWeights.at (refParticleID);
258306 }
259307 return noWeights;
@@ -266,6 +314,7 @@ void ParticleCompositionCorrection::process(aod::McCollisions::iterator const&,
266314 float dNdEtafid = 0 .f ;
267315
268316 for (const auto & particle : particles) {
317+
269318 if (!particle.isPhysicalPrimary ()) {
270319 continue ;
271320 }
@@ -288,6 +337,8 @@ void ParticleCompositionCorrection::process(aod::McCollisions::iterator const&,
288337 histos.fill (HIST (" multDist_fidVsINELg0" ), dNdEta, dNdEtafid);
289338 }
290339
340+ // LOGP(info, "MCB: ------- New event with dNdeta = {} in |eta| < 0.8 -------", dNdEtafid);
341+
291342 std::map<int32_t , std::tuple<float , float , float >> storedWeights;
292343 for (const auto & particle : particles) {
293344 auto [weight, weightSysUp, weightSysDown] = getWeights (particles, particle, storedWeights, dNdEta);
0 commit comments