88// In applying this license CERN does not waive the privileges and immunities
99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
11- // /
11+
1212// / \file associateMCinfoPhoton.cxx
13- // /
1413// / \brief This code produces reduced events for photon analyses
15- // /
1614// / \author Daiki Sekihata (daiki.sekihata@cern.ch)
17- // /
1815
1916#include " PWGEM/PhotonMeson/DataModel/GammaTablesRedux.h"
2017#include " PWGEM/PhotonMeson/DataModel/gammaTables.h"
4643#include < cstdlib>
4744#include < map>
4845#include < string_view>
46+ #include < unordered_map>
4947#include < vector>
5048
5149using namespace o2 ;
@@ -60,6 +58,11 @@ using TracksMC = soa::Join<aod::TracksIU, aod::McTrackLabels>;
6058using FwdTracksMC = soa::Join<aod::FwdTracks, aod::McFwdTrackLabels>;
6159using MyEMCClusters = soa::Join<aod::MinClusters, aod::EMCClusterMCLabels>;
6260
61+ struct Counter {
62+ int particles{0 };
63+ int events{0 };
64+ };
65+
6366struct AssociateMCInfoPhoton {
6467 enum SubSystem {
6568 kPCM = 0x1 ,
@@ -82,6 +85,9 @@ struct AssociateMCInfoPhoton {
8285 Configurable<float > max_rxy_gen{" max_rxy_gen" , 100 , " max rxy to store generated information" };
8386 Configurable<bool > requireGammaGammaDecay{" requireGammaGammaDecay" , false , " require gamma gamma decay for generated pi0 and eta meson" };
8487 Configurable<float > cfg_max_eta_photon{" cfg_max_eta_gamma" , 0.8 , " max eta for photons at PV" };
88+ Configurable<float > maxPt{" maxPt" , 20 .f , " max pT for BinnedGenPts table" };
89+ Configurable<float > maxY{" maxY" , 0 .9f , " max |rapidity| for BinnedGenPts table" };
90+ Configurable<bool > doStoreAllDaughters{" doStoreAllDaughters" , false , " flag to enable storing of all photon, pi0, eta, eta' and omega daughters. This will increase the dervied data size!" };
8591
8692 HistogramRegistry registry{" EMMCEvent" };
8793
@@ -136,16 +142,72 @@ struct AssociateMCInfoPhoton {
136142 std::vector<uint16_t > genPi0; // primary, pt, y
137143 std::vector<uint16_t > genEta; // primary, pt, y
138144
145+ template <o2::soa::is_iterator TMCParticle, o2::soa::is_iterator TMCDaughter>
146+ void selectDaughtersToStore (TMCParticle& particle, int64_t mcParticleSize, TMCDaughter& daughterIter, int eventIdx, std::unordered_map<uint64_t , int >& fNewLabels , std::map<uint64_t , int >& fNewLabelsReversed , std::unordered_map<uint64_t , int >& fEventIdx , Counter& fCounter )
147+ {
148+ if (!particle.has_daughters ()) {
149+ return ;
150+ }
151+ for (int daughterId = particle.daughtersIds ()[0 ]; daughterId <= particle.daughtersIds ()[1 ]; ++daughterId) {
152+ if (daughterId < mcParticleSize) {
153+ daughterIter.setCursor (daughterId);
154+ if (!fNewLabels .contains (daughterIter.globalIndex ())) {
155+ fNewLabels [daughterIter.globalIndex ()] = fCounter .particles ;
156+ fNewLabelsReversed [fCounter .particles ] = daughterIter.globalIndex ();
157+ fEventIdx [daughterIter.globalIndex ()] = eventIdx;
158+ fCounter .particles ++;
159+ }
160+ }
161+ }
162+ }
163+
164+ template <o2::soa::is_iterator TMCParticle, o2::soa::is_iterator TMCCollision>
165+ void selectMothersToStore (int motherId, int64_t mcParticleSize, TMCParticle& motherParticle, TMCParticle& daughterIter, TMCCollision const & mcCollisionIter, std::unordered_map<uint64_t , int >& fNewLabels , std::map<uint64_t , int >& fNewLabelsReversed , std::unordered_map<uint64_t , int >& fEventIdx , std::unordered_map<uint64_t , int >& fEventLabels , Counter& fCounter )
166+ {
167+ while (motherId > -1 ) {
168+ if (motherId < mcParticleSize) { // protect against bad mother indices. why is this needed?
169+ motherParticle.setCursor (motherId);
170+ int eventIdx = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
171+
172+ // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
173+ if (!fNewLabels .contains (motherParticle.globalIndex ())) {
174+ fNewLabels [motherParticle.globalIndex ()] = fCounter .particles ;
175+ fNewLabelsReversed [fCounter .particles ] = motherParticle.globalIndex ();
176+ fEventIdx [motherParticle.globalIndex ()] = eventIdx;
177+ fCounter .particles ++;
178+ }
179+ // If this ancestor is a photon, pi0, eta, omega or eta prime store all its daughters
180+ if ((doStoreAllDaughters) && (std::abs (motherParticle.pdgCode ()) == PDG_t::kGamma ||
181+ std::abs (motherParticle.pdgCode ()) == PDG_t::kPi0 ||
182+ std::abs (motherParticle.pdgCode ()) == o2::constants::physics::Pdg::kEta ||
183+ std::abs (motherParticle.pdgCode ()) == o2::constants::physics::Pdg::kEtaPrime ||
184+ std::abs (motherParticle.pdgCode ()) == o2::constants::physics::Pdg::kOmega )) {
185+ selectDaughtersToStore (motherParticle, mcParticleSize, daughterIter,
186+ eventIdx, fNewLabels , fNewLabelsReversed ,
187+ fEventIdx , fCounter );
188+ }
189+
190+ if (motherParticle.has_mothers ()) {
191+ motherId = motherParticle.mothersIds ()[0 ]; // first mother index
192+ } else {
193+ motherId = -999 ;
194+ }
195+ } else {
196+ motherId = -999 ;
197+ }
198+ } // end of mother chain loop
199+ }
200+
139201 template <uint8_t system, typename TTracks, typename TFwdTracks, typename TPCMs, typename TPCMLegs, typename TPHOSs, typename TEMCs, typename TEMPrimaryElectrons>
140202 void skimmingMC (MyCollisionsMC const & collisions, aod::BCs const &, aod::McCollisions const & mcCollisions, aod::McParticles const & mcParticles, TTracks const & o2tracks, TFwdTracks const &, TPCMs const & v0photons, TPCMLegs const & legs, TPHOSs const &, TEMCs const & emcclusters, TEMPrimaryElectrons const & emprimaryelectrons)
141203 {
142204 // temporary variables used for the indexing of the skimmed MC stack
143- std::map <uint64_t , int > fNewLabels ;
205+ std::unordered_map <uint64_t , int > fNewLabels ;
144206 std::map<uint64_t , int > fNewLabelsReversed ;
145207 // std::map<uint64_t, uint16_t> fMCFlags;
146- std::map <uint64_t , int > fEventIdx ;
147- std::map <uint64_t , int > fEventLabels ;
148- int fCounters [ 2 ] = { 0 , 0 }; // ! [0] - particle counter, [1] - event counter
208+ std::unordered_map <uint64_t , int > fEventIdx ;
209+ std::unordered_map <uint64_t , int > fEventLabels ;
210+ Counter fCounter {. particles = 0 , . events = 0 }; // ! [0] - particle counter, [1] - event counter
149211 auto hBinFinder = registry.get <TH2>(HIST (" Generated/h2PtY_Gamma" ));
150212
151213 // collision iterator from EMCal cluster
@@ -156,6 +218,7 @@ struct AssociateMCInfoPhoton {
156218
157219 // mc particles iterator for mother
158220 auto motherParticle = mcParticles.begin ();
221+ auto daughterIter = mcParticles.begin ();
159222
160223 // mc particles iterator for mother and other mc particles
161224 auto mcParticleIter = mcParticles.begin ();
@@ -186,7 +249,7 @@ struct AssociateMCInfoPhoton {
186249 auto groupedMcParticles = mcParticles.sliceBy (perMcCollision, mcCollisionIter.globalIndex ());
187250
188251 for (const auto & mcParticle : groupedMcParticles) { // store necessary information for denominator of efficiency
189- if ((mcParticle.isPhysicalPrimary () || mcParticle.producedByGenerator ()) && std::fabs (mcParticle.y ()) < 0 . 9f && mcParticle.pt () < 20 . f ) {
252+ if ((mcParticle.isPhysicalPrimary () || mcParticle.producedByGenerator ()) && std::fabs (mcParticle.y ()) < maxY && mcParticle.pt () < maxPt ) {
190253 auto binNumber = hBinFinder->FindBin (mcParticle.pt (), std::fabs (mcParticle.y ())); // caution: pack
191254
192255 bool isMesonAccepted = false ;
@@ -229,8 +292,8 @@ struct AssociateMCInfoPhoton {
229292 // make an entry for this MC event only if it was not already added to the table
230293 if (!(fEventLabels .find (mcCollisionIter.globalIndex ()) != fEventLabels .end ())) {
231294 mcevents (mcCollisionIter.globalIndex (), mcCollisionIter.generatorsID (), mcCollisionIter.posX (), mcCollisionIter.posY (), mcCollisionIter.posZ (), mcCollisionIter.impactParameter (), mcCollisionIter.eventPlaneAngle ());
232- fEventLabels [mcCollisionIter.globalIndex ()] = fCounters [ 1 ] ;
233- fCounters [ 1 ] ++;
295+ fEventLabels [mcCollisionIter.globalIndex ()] = fCounter . events ;
296+ fCounter . events ++;
234297 binnedGenPt (genGamma, genPi0, genEta);
235298 }
236299
@@ -259,21 +322,21 @@ struct AssociateMCInfoPhoton {
259322
260323 if (motherParticle.pdgCode () == PDG_t::kGamma && (motherParticle.isPhysicalPrimary () || motherParticle.producedByGenerator ()) && std::fabs (motherParticle.eta ()) < max_eta_gen_secondary) {
261324 // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
262- if (!( fNewLabels .find (mcParticle.globalIndex ()) != fNewLabels . end ())) { // store electron information. !!Not photon!!
263- fNewLabels [mcParticle.globalIndex ()] = fCounters [ 0 ] ;
264- fNewLabelsReversed [fCounters [ 0 ] ] = mcParticle.globalIndex ();
325+ if (!fNewLabels .contains (mcParticle.globalIndex ())) { // store electron information. !!Not photon!!
326+ fNewLabels [mcParticle.globalIndex ()] = fCounter . particles ;
327+ fNewLabelsReversed [fCounter . particles ] = mcParticle.globalIndex ();
265328 // fMCFlags[mcParticle.globalIndex()] = mcflags;
266329 fEventIdx [mcParticle.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
267- fCounters [ 0 ] ++;
330+ fCounter . particles ++;
268331 }
269332
270333 // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
271- if (!( fNewLabels .find (motherParticle.globalIndex ()) != fNewLabels . end ())) { // store conversion photon
272- fNewLabels [motherParticle.globalIndex ()] = fCounters [ 0 ] ;
273- fNewLabelsReversed [fCounters [ 0 ] ] = motherParticle.globalIndex ();
334+ if (!fNewLabels .contains (motherParticle.globalIndex ())) { // store conversion photon
335+ fNewLabels [motherParticle.globalIndex ()] = fCounter . particles ;
336+ fNewLabelsReversed [fCounter . particles ] = motherParticle.globalIndex ();
274337 // fMCFlags[motherParticle.globalIndex()] = mcflags;
275338 fEventIdx [motherParticle.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
276- fCounters [ 0 ] ++;
339+ fCounter . particles ++;
277340 }
278341 }
279342 }
@@ -312,42 +375,20 @@ struct AssociateMCInfoPhoton {
312375 // LOGF(info, "mcParticleIter.globalIndex() = %d, mcParticleIter.index() = %d", mcParticleIter.globalIndex(), mcParticleIter.index()); // these are exactly the same.
313376
314377 // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
315- if (!(fNewLabels .find (mcParticleIter.globalIndex ()) != fNewLabels .end ())) {
316- fNewLabels [mcParticleIter.globalIndex ()] = fCounters [0 ];
317- fNewLabelsReversed [fCounters [0 ]] = mcParticleIter.globalIndex ();
318- // fMCFlags[mcParticleIter.globalIndex()] = mcflags;
378+ auto [iter, isNew] = fNewLabels .try_emplace (mcParticleIter.globalIndex (), fCounter .particles );
379+ if (isNew) {
380+ fNewLabelsReversed [fCounter .particles ] = mcParticleIter.globalIndex ();
319381 fEventIdx [mcParticleIter.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
320- fCounters [ 0 ] ++;
382+ fCounter . particles ++;
321383 }
322- v0legmclabels (fNewLabels . find (mcParticleIter. index ()) ->second , o2TrackIter.mcMask ());
384+ v0legmclabels (iter ->second , o2TrackIter.mcMask ());
323385
324386 // Next, store mother-chain of this reconstructed track.
325387 int motherid = -999 ; // first mother index
326388 if (mcParticleIter.has_mothers ()) {
327389 motherid = mcParticleIter.mothersIds ()[0 ]; // first mother index
328390 }
329- while (motherid > -1 ) {
330- if (motherid < mcParticles.size ()) { // protect against bad mother indices. why is this needed?
331- motherParticle.setCursor (motherid);
332-
333- // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
334- if (!(fNewLabels .find (motherParticle.globalIndex ()) != fNewLabels .end ())) {
335- fNewLabels [motherParticle.globalIndex ()] = fCounters [0 ];
336- fNewLabelsReversed [fCounters [0 ]] = motherParticle.globalIndex ();
337- // fMCFlags[motherParticle.globalIndex()] = mcflags;
338- fEventIdx [motherParticle.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
339- fCounters [0 ]++;
340- }
341-
342- if (motherParticle.has_mothers ()) {
343- motherid = motherParticle.mothersIds ()[0 ]; // first mother index
344- } else {
345- motherid = -999 ;
346- }
347- } else {
348- motherid = -999 ;
349- }
350- } // end of mother chain loop
391+ selectMothersToStore (motherid, mcParticles.size (), motherParticle, daughterIter, mcCollisionIter, fNewLabels , fNewLabelsReversed , fEventIdx , fEventLabels , fCounter );
351392 } // end of leg loop
352393 } // end of v0 loop
353394 }
@@ -369,43 +410,20 @@ struct AssociateMCInfoPhoton {
369410 mcParticleIter.setCursor (o2TrackIter.mcParticleId ());
370411
371412 // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
372- if (!(fNewLabels .find (mcParticleIter.globalIndex ()) != fNewLabels .end ())) {
373- fNewLabels [mcParticleIter.globalIndex ()] = fCounters [0 ];
374- fNewLabelsReversed [fCounters [0 ]] = mcParticleIter.globalIndex ();
375- // fMCFlags[mcParticleIter.globalIndex()] = mcflags;
413+ auto [iter, isNew] = fNewLabels .try_emplace (mcParticleIter.globalIndex (), fCounter .particles );
414+ if (isNew) {
415+ fNewLabelsReversed [fCounter .particles ] = mcParticleIter.globalIndex ();
376416 fEventIdx [mcParticleIter.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
377- fCounters [ 0 ] ++;
417+ fCounter . particles ++;
378418 }
379- emprimaryelectronmclabels (fNewLabels . find (mcParticleIter. index ()) ->second , o2TrackIter.mcMask ());
419+ emprimaryelectronmclabels (iter ->second , o2TrackIter.mcMask ());
380420
381421 // Next, store mother-chain of this reconstructed track.
382422 int motherid = -999 ; // first mother index
383423 if (mcParticleIter.has_mothers ()) {
384424 motherid = mcParticleIter.mothersIds ()[0 ]; // first mother index
385425 }
386- while (motherid > -1 ) {
387- if (motherid < mcParticles.size ()) { // protect against bad mother indices. why is this needed?
388- motherParticle.setCursor (motherid);
389-
390- // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
391- if (!(fNewLabels .find (motherParticle.globalIndex ()) != fNewLabels .end ())) {
392- fNewLabels [motherParticle.globalIndex ()] = fCounters [0 ];
393- fNewLabelsReversed [fCounters [0 ]] = motherParticle.globalIndex ();
394- // fMCFlags[motherParticle.globalIndex()] = mcflags;
395- fEventIdx [motherParticle.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
396- fCounters [0 ]++;
397- }
398-
399- if (motherParticle.has_mothers ()) {
400- motherid = motherParticle.mothersIds ()[0 ]; // first mother index
401- } else {
402- motherid = -999 ;
403- }
404- } else {
405- motherid = -999 ;
406- }
407- } // end of mother chain loop
408-
426+ selectMothersToStore (motherid, mcParticles.size (), motherParticle, daughterIter, mcCollisionIter, fNewLabels , fNewLabelsReversed , fEventIdx , fEventLabels , fCounter );
409427 } // end of em primary electron loop
410428 }
411429
@@ -430,42 +448,21 @@ struct AssociateMCInfoPhoton {
430448 mcPhoton.setCursor (emcParticleId);
431449
432450 // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
433- if (!( fNewLabels .find (mcPhoton.globalIndex ()) != fNewLabels . end ())) {
434- fNewLabels [mcPhoton. globalIndex ()] = fCounters [ 0 ];
435- fNewLabelsReversed [fCounters [ 0 ] ] = mcPhoton.globalIndex ();
451+ auto [iter, isNew] = fNewLabels .try_emplace (mcPhoton.globalIndex (), fCounter . particles );
452+ if (isNew) {
453+ fNewLabelsReversed [fCounter . particles ] = mcPhoton.globalIndex ();
436454 fEventIdx [mcPhoton.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
437- fCounters [ 0 ] ++;
455+ fCounter . particles ++;
438456 }
439- vEmcMcParticleIds.emplace_back (fNewLabels . find (mcPhoton. index ()) ->second );
457+ vEmcMcParticleIds.emplace_back (iter ->second );
440458 // ememcclustermclabels(fNewLabels.find(mcPhoton.index())->second);
441459
442460 // Next, store mother-chain of this reconstructed track.
443461 int motherid = -999 ; // first mother index
444462 if (mcPhoton.has_mothers ()) {
445463 motherid = mcPhoton.mothersIds ()[0 ]; // first mother index
446464 }
447- while (motherid > -1 ) {
448- if (motherid < mcParticles.size ()) { // protect against bad mother indices. why is this needed?
449- motherParticle.setCursor (motherid);
450-
451- // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack
452- if (!(fNewLabels .find (motherParticle.globalIndex ()) != fNewLabels .end ())) {
453- fNewLabels [motherParticle.globalIndex ()] = fCounters [0 ];
454- fNewLabelsReversed [fCounters [0 ]] = motherParticle.globalIndex ();
455- fEventIdx [motherParticle.globalIndex ()] = fEventLabels .find (mcCollisionIter.globalIndex ())->second ;
456- fCounters [0 ]++;
457- }
458-
459- if (motherParticle.has_mothers ()) {
460- motherid = motherParticle.mothersIds ()[0 ]; // first mother index
461- } else {
462- motherid = -999 ;
463- }
464- } else {
465- motherid = -999 ;
466- }
467- } // end of mother chain loop
468-
465+ selectMothersToStore (motherid, mcParticles.size (), motherParticle, daughterIter, mcCollisionIter, fNewLabels , fNewLabelsReversed , fEventIdx , fEventLabels , fCounter );
469466 } // end of loop over mc particles of the current emc cluster
470467 ememcclustermclabels (vEmcMcParticleIds);
471468
@@ -481,8 +478,9 @@ struct AssociateMCInfoPhoton {
481478 if (mcParticleIter.has_mothers ()) {
482479 for (const auto & m : mcParticleIter.mothersIds ()) {
483480 if (m < mcParticles.size ()) { // protect against bad mother indices
484- if (fNewLabels .find (m) != fNewLabels .end ()) {
485- mothers.push_back (fNewLabels .find (m)->second );
481+ auto iter = fNewLabels .find (m);
482+ if (iter != fNewLabels .end ()) {
483+ mothers.push_back (iter->second );
486484 }
487485 } else {
488486 LOG (info) << " Mother label (" << m << " ) exceeds the McParticles size (" << mcParticles.size () << " )" ;
@@ -500,8 +498,9 @@ struct AssociateMCInfoPhoton {
500498 if (d < mcParticles.size ()) { // protect against bad daughter indices
501499 // auto dau_tmp = mcParticles.iteratorAt(d);
502500 // LOGF(info, "daughter pdg = %d", dau_tmp.pdgCode());
503- if (fNewLabels .find (d) != fNewLabels .end ()) {
504- daughters.push_back (fNewLabels .find (d)->second );
501+ auto iter = fNewLabels .find (d);
502+ if (iter != fNewLabels .end ()) {
503+ daughters.push_back (iter->second );
505504 }
506505 } else {
507506 LOG (error) << " Daughter label (" << d << " ) exceeds the McParticles size (" << mcParticles.size () << " )" ;
@@ -521,11 +520,11 @@ struct AssociateMCInfoPhoton {
521520 // fMCFlags.clear();
522521 fEventIdx .clear ();
523522 fEventLabels .clear ();
524- fCounters [ 0 ] = 0 ;
525- fCounters [ 1 ] = 0 ;
523+ fCounter . particles = 0 ;
524+ fCounter . events = 0 ;
526525 } // end of skimmingMC
527526
528- template <typename Daughters>
527+ template <o2::soa::is_table Daughters>
529528 inline bool areTwoPhotonDaughtersAccepted (const Daughters& lDaughters, float maxEta)
530529 {
531530 if (lDaughters.size () != 2 ) {
0 commit comments