@@ -94,16 +94,19 @@ enum class TruthClass {
9494 PhotonElectronSamePi0, // 4: photon + electron cluster, same Pi0
9595 PhotonElectronDiffPi0, // 5: photon + electron cluster, different Pi0s
9696 PhotonElectronOnePi0, // 6: photon + electron cluster, only one from a Pi0
97- PhotonElectronBS , // 7: photon + electron cluster, from Bremsstrahlung
97+ BSPhotonElectron , // 7: photon + electron cluster, from Bremsstrahlung
9898
9999 ElectronPairSamePi0, // 8: e+e cluster pair, same Pi0 (conversion and/or Dalitz)
100100 ElectronPairDiffPi0, // 9: e+e cluster pair, different Pi0s
101101 ElectronPairOnePi0, // 10: e+e cluster pair, only one from a Pi0
102102
103- SplitPhotonCluster, // 11: one photon producing two clusters
104- SplitLeptonCluster, // 12: one lepton producing two clusters
103+ SplitPhotonCluster, // 11: one photon producing two clusters
104+ SplitLeptonCluster, // 12: one lepton producing two clusters
105+ PhotonBSPhotonPair, // 13: photon + photon from Bremsstrahlung
106+ ElectronBSPhotonPair, // 14: one cluster from Bremsstrahlung and one electron cluster except case BSPhotonElectron
107+ BSPhotonPair, // 15: both photons from Bremsstrahlung
105108
106- Background, // 13 : else / uncorrelated
109+ Background, // 16 : else / uncorrelated
107110
108111 NClasses
109112};
@@ -132,15 +135,17 @@ struct ClusterMcInfo {
132135 bool isFromBremsstrahlung = false ;
133136 int convMotherId = -1 ;
134137 int photonId = -1 ;
138+ float purity = 0 ;
135139};
136140
137141template <o2::soa::is_iterator TGroup, o2::soa::is_iterator TIter, o2::soa::is_table McParticles>
138142ClusterMcInfo classifyCluster (const TGroup& g, TIter& mcCluster, TIter& mcClusterLooper, TIter& mcClusterLooper2, McParticles const & mcParticles)
139143{
140144 ClusterMcInfo info;
141145 mcCluster.setCursor (g.emmcparticleIds ()[0 ]);
142- info.isFromBremsstrahlung = isFromBremsstrahlung (mcCluster, mcClusterLooper);
146+ info.isFromBremsstrahlung = isFromBremsstrahlung (mcCluster, mcClusterLooper); // particle has to be a photon and it has to have a e+ or e- as mother!
143147 float leadingAmplitude = g.amplitude ()[0 ];
148+ info.purity = leadingAmplitude;
144149 if (std::abs (mcCluster.pdgCode ()) == PDG_t::kElectron ) {
145150 info.isLepton = true ;
146151 info.convMotherId = getMotherIndexFromChain (mcCluster, mcClusterLooper, PDG_t::kGamma );
@@ -178,18 +183,18 @@ struct EmcalPhotonMcTask {
178183
179184 static constexpr std::array<const char *, static_cast <size_t >(TruthClass::NClasses)> kTruthClassNames = {
180185 " Conversion" , " PhotonPairSamePi0" , " PhotonPairDiffPi0" , " PhotonPairOnePi0" ,
181- " PhotonElectronSamePi0" , " PhotonElectronDiffPi0" , " PhotonElectronOnePi0" , " PhotonElectronBS " ,
186+ " PhotonElectronSamePi0" , " PhotonElectronDiffPi0" , " PhotonElectronOnePi0" , " BSPhotonElectron " ,
182187 " ElectronPairSamePi0" , " ElectronPairDiffPi0" , " ElectronPairOnePi0" ,
183188 " SplitPhotonCluster" , " SplitLeptonCluster" , " Background" };
184189
185- Produces<aod::ConvTagCandidates > convTagCandidates;
190+ Produces<aod::ConvTagCandidates_001 > convTagCandidates;
186191
187192 Configurable<std::string> ccdbUrl{" ccdbUrl" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
188193 Configurable<std::string> grpPath{" grpPath" , " GLO/GRP/GRP" , " Path of the grp file" };
189194 Configurable<std::string> grpmagPath{" grpmagPath" , " GLO/Config/GRPMagField" , " CCDB path of the GRPMagField object" };
190195 Configurable<bool > skipGRPOquery{" skipGRPOquery" , true , " skip grpo query" };
191196 Configurable<bool > writeTable{" writeTable" , true , " write table for ML." };
192- Configurable<std::vector<int >> classPrescale{" classPrescale" , {1 , 1 , 700 , 25 , 1 , 350 , 15 , 1 , 1 , 35 , 2 , 1 , 1 , 1000 }, " prescale factor per TruthClass, indexed 0..10 matching the enum order" };
197+ Configurable<std::vector<int >> classPrescale{" classPrescale" , {1 , 1 , 700 , 25 , 1 , 350 , 15 , 1 , 1 , 35 , 2 , 1 , 1 , 1 , 1 , 1 , 1000 }, " prescale factor per TruthClass, indexed 0..10 matching the enum order" };
193198 Configurable<uint32_t > bkgPrescaleSeed{" bkgPrescaleSeed" , 42 , " seed for the background-prescale RNG" };
194199
195200 // configurable axis
@@ -334,6 +339,7 @@ struct EmcalPhotonMcTask {
334339 o2::aod::pwgem::photonmeson::utils::eventhistogram::addEventHistograms (®istry);
335340
336341 const AxisSpec thnAxisERec{thnConfigAxisPt, " #it{E}_{Rec} (GeV)" };
342+ const AxisSpec thnAxisPtRec{thnConfigAxisPt, " #it{p}_{T} (GeV/#it{c})" };
337343 const AxisSpec thnAxisInvMass{thnConfigAxisInvMass, " #it{M}_{#gamma#gamma} (GeV/#it{c}^{2})" };
338344
339345 const AxisSpec thnAxisrConvRec{100 , 0 , 500 , " #it{R}_{rec}" };
@@ -354,7 +360,7 @@ struct EmcalPhotonMcTask {
354360 thnAxisCentOrMult = {thnConfigAxisMult, " FT0C Multiplicity" };
355361 }
356362
357- auto hTruthLabel = registry.add <TH1 >(" hTruthLabel" , " Truth label distribution;;Counts" , HistType::kTH1D , {{static_cast <int >(TruthClass::NClasses), -0.5 , static_cast <double >(TruthClass::NClasses) - 0.5 }});
363+ auto hTruthLabel = registry.add <TH2 >(" hTruthLabel" , " Truth label distribution;;Counts" , HistType::kTH2D , {{static_cast <int >(TruthClass::NClasses), -0.5 , static_cast <double >(TruthClass::NClasses) - 0.5 }, thnAxisPtRec });
358364
359365 // set bin labels once at init, so histogram is human-readable without decoding the enum
360366 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::Conversion) + 1 , " Conversion" );
@@ -364,12 +370,15 @@ struct EmcalPhotonMcTask {
364370 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::PhotonElectronSamePi0) + 1 , " PhotonElectronSamePi0" );
365371 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::PhotonElectronDiffPi0) + 1 , " PhotonElectronDiffPi0" );
366372 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::PhotonElectronOnePi0) + 1 , " PhotonElectronOnePi0" );
367- hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::PhotonElectronBS ) + 1 , " PhotonElectronBS " );
373+ hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::BSPhotonElectron ) + 1 , " BSPhotonElectron " );
368374 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::ElectronPairSamePi0) + 1 , " ElectronPairSamePi0" );
369375 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::ElectronPairDiffPi0) + 1 , " ElectronPairDiffPi0" );
370376 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::ElectronPairOnePi0) + 1 , " ElectronPairOnePi0" );
371377 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::SplitPhotonCluster) + 1 , " SplitPhotonCluster" );
372378 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::SplitLeptonCluster) + 1 , " SplitLeptonCluster" );
379+ hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::PhotonBSPhotonPair) + 1 , " PhotonBSPhotonPair" );
380+ hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::ElectronBSPhotonPair) + 1 , " ElectronBSPhotonPair" );
381+ hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::BSPhotonPair) + 1 , " BSPhotonPair" );
373382 hTruthLabel->GetXaxis ()->SetBinLabel (static_cast <int >(TruthClass::Background) + 1 , " Background" );
374383
375384 auto hPi0BothResolvedLost = registry.add <TH1 >(" EMCal/hPi0BothResolvedLost" , " Confusion matrix for conversion tagging" , HistType::kTH1D , {{2 , -0.5 , 1.5 }});
@@ -582,7 +591,7 @@ struct EmcalPhotonMcTask {
582591 bool areConversionLegs = false ;
583592 bool areSplitPhotonCluster = false ;
584593 bool areSplitLeptonCluster = false ;
585- bool arePhotonElectronBS = false ;
594+ bool areBSPhotonElectron = false ;
586595
587596 auto c1 = classifyCluster (g1, mcCluster1, mcClusterLooper, mcClusterLooper2, mcParticles);
588597 auto c2 = classifyCluster (g2, mcCluster2, mcClusterLooper, mcClusterLooper2, mcParticles);
@@ -599,6 +608,9 @@ struct EmcalPhotonMcTask {
599608 }
600609 }
601610
611+ const bool isAnyBSPhoton = c1.isFromBremsstrahlung || c2.isFromBremsstrahlung ;
612+ const bool areBSPhotons = c1.isFromBremsstrahlung && c2.isFromBremsstrahlung ;
613+
602614 // if they are not a split cluster check for proper conversion pair
603615 if (!isSameDominantParticle && c1.isFromConv && c2.isFromConv && c1.convMotherId == c2.convMotherId ) {
604616 emcFlagsFromTrueConversion.set (g1.globalIndex ());
@@ -616,7 +628,7 @@ struct EmcalPhotonMcTask {
616628 // bremsstrahlung: one side is a photon born from the other side's lepton lineage
617629 const bool photonIsBS = (c1.isPhoton && c1.isFromBremsstrahlung ) || (c2.isPhoton && c2.isFromBremsstrahlung );
618630 if (photonIsBS && ((c1.isLepton && c2.isPhoton ) || (c2.isLepton && c1.isPhoton ))) {
619- arePhotonElectronBS = true ;
631+ areBSPhotonElectron = true ;
620632 } else {
621633 areFromSamePi0 = true ;
622634 emcFlagsFromTrueMesonSameGamma.set (g1.globalIndex ());
@@ -637,8 +649,14 @@ struct EmcalPhotonMcTask {
637649 bTruthLabel = static_cast <int8_t >(TruthClass::SplitLeptonCluster);
638650 } else if (areConversionLegs) {
639651 bTruthLabel = static_cast <int8_t >(TruthClass::Conversion);
640- } else if (arePhotonElectronBS) {
641- bTruthLabel = static_cast <int8_t >(TruthClass::PhotonElectronBS);
652+ } else if (areBSPhotonElectron) {
653+ bTruthLabel = static_cast <int8_t >(TruthClass::BSPhotonElectron);
654+ } else if (areBSPhotons && (c1.isFromPi0 || c2.isFromPi0 )) {
655+ bTruthLabel = static_cast <int8_t >(TruthClass::BSPhotonPair);
656+ } else if (isAnyBSPhoton && (c1.isFromPi0 || c2.isFromPi0 ) && ((c1.isPhoton && c2.isLepton ) || (c2.isPhoton && c1.isLepton ))) {
657+ bTruthLabel = static_cast <int8_t >(TruthClass::ElectronBSPhotonPair);
658+ } else if (isAnyBSPhoton && (c1.isFromPi0 || c2.isFromPi0 ) && (c1.isPhoton && c2.isPhoton )) {
659+ bTruthLabel = static_cast <int8_t >(TruthClass::PhotonBSPhotonPair);
642660 } else if (areFromSamePi0) {
643661 if ((c1.isLepton && c2.isPhoton ) || (c2.isLepton && c1.isPhoton )) {
644662 bTruthLabel = static_cast <int8_t >(TruthClass::PhotonElectronSamePi0);
@@ -665,13 +683,13 @@ struct EmcalPhotonMcTask {
665683 }
666684 }
667685
668- registry.fill (HIST (" hTruthLabel" ), bTruthLabel);
686+ registry.fill (HIST (" hTruthLabel" ), bTruthLabel, vMeson. Pt () );
669687
670688 // final tree values plus filling
671689 const int prescale = classPrescale.value [static_cast <uint>(bTruthLabel)];
672690 const bool keepThisRow = (prescale <= 1 ) || (std::uniform_int_distribution<int >(0 , prescale - 1 )(mRandGen ) == 0 );
673691 if (writeTable.value && keepThisRow) {
674- convTagCandidates (collision.globalIndex (), vMeson.M (), harmonicET, deltaEta, deltaPhi, phiV, g1.e (), g2.e (), g1.m02 (), g2.m02 (), g1.time (), g2.time (), g1.nCells (), g2.nCells (), bTruthLabel, centOrMult);
692+ convTagCandidates (collision.globalIndex (), vMeson.M (), harmonicET, deltaEta, deltaPhi, phiV, g1.e (), g2.e (), g1.m02 (), g2.m02 (), g1.time (), g2.time (), g1.nCells (), g2.nCells (), c1. purity , c2. purity , bTruthLabel, centOrMult);
675693 }
676694 } // pair loop
677695 } // collision loop
0 commit comments