@@ -349,6 +349,52 @@ struct DeltaAnalysis {
349349 histos.add (" QAChecks/hGenPionAntiDeltaPlusPlus" , " Gen pion from #bar{#Delta}^{++}" , kTH1F , {ptAxis});
350350 histos.add (" QAChecks/hGenPionDeltaZero" , " Gen pion from #Delta^{0}" , kTH1F , {ptAxis});
351351 histos.add (" QAChecks/hGenPionAntiDeltaZero" , " Gen pion from #bar{#Delta}^{0}" , kTH1F , {ptAxis});
352+
353+ // reconstructed-level (pre-truth-matching) invariant mass histograms for MC-reconstructed candidates
354+ histos.add (" AnalysisMCReco/hDeltaPlusPlusInvMassReco" , " #Delta^{++} invariant mass - MC reconstructed (pre-truth-matching)" , kTH2F , {ptAxis, massAxis});
355+ histos.add (" AnalysisMCReco/hAntiDeltaPlusPlusInvMassReco" , " #bar{#Delta}^{++} invariant mass - MC reconstructed (pre-truth-matching)" , kTH2F , {ptAxis, massAxis});
356+ histos.add (" AnalysisMCReco/hDeltaZeroInvMassReco" , " #Delta^{0} invariant mass - MC reconstructed (pre-truth-matching)" , kTH2F , {ptAxis, massAxis});
357+ histos.add (" AnalysisMCReco/hAntiDeltaZeroInvMassReco" , " #bar{#Delta}^{0} invariant mass - MC reconstructed (pre-truth-matching)" , kTH2F , {ptAxis, massAxis});
358+
359+ histos.add (" THnSparseMCReco/hDeltaPlusPlusReco" , " THnSparse #Delta^{++} MC reconstructed (pre-truth-matching)" , kTHnSparseF , {massAxis, ptAxis, centAxis, rapAxis});
360+ histos.add (" THnSparseMCReco/hAntiDeltaPlusPlusReco" , " THnSparse #bar{#Delta}^{++} MC reconstructed (pre-truth-matching)" , kTHnSparseF , {massAxis, ptAxis, centAxis, rapAxis});
361+ histos.add (" THnSparseMCReco/hDeltaZeroReco" , " THnSparse #Delta^{0} MC reconstructed (pre-truth-matching)" , kTHnSparseF , {massAxis, ptAxis, centAxis, rapAxis});
362+ histos.add (" THnSparseMCReco/hAntiDeltaZeroReco" , " THnSparse #bar{#Delta}^{0} MC reconstructed (pre-truth-matching)" , kTHnSparseF , {massAxis, ptAxis, centAxis, rapAxis});
363+
364+ // detector QA for reconstructed MC tracks,no truth matching required ──
365+ histos.add (" QAMC/Proton/dcaXYvsPt" , " Proton DCA_{xy} vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, dcaXYaxis});
366+ histos.add (" QAMC/Proton/dcaZvsPt" , " Proton DCA_{z} vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, dcaZaxis});
367+ histos.add (" QAMC/Proton/tpcNSigmaVsMomentum" , " Proton TPC n#sigma vs p (MC reco, after cuts)" , kTH2F , {momentumAxis, nSigmaTPCaxis});
368+ histos.add (" QAMC/Proton/tpcNSigmaVsPt" , " Proton TPC n#sigma vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
369+ histos.add (" QAMC/Proton/tpcNSigmaVsCentrality" , " Proton TPC n#sigma vs centrality (MC reco)" , kTH2F , {centAxis, nSigmaTPCaxis});
370+ histos.add (" QAMC/Proton/tofNSigmaVsMomentum" , " Proton TOF n#sigma vs p (MC reco, after cuts)" , kTH2F , {momentumAxis, nSigmaTOFaxis});
371+ histos.add (" QAMC/Proton/tofNSigmaVsPt" , " Proton TOF n#sigma vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, nSigmaTOFaxis});
372+ histos.add (" QAMC/Proton/tofNSigmaVsCentrality" , " Proton TOF n#sigma vs centrality (MC reco)" , kTH2F , {centAxis, nSigmaTOFaxis});
373+ histos.add (" QAMC/Proton/tofNSigmaVsTPCNSigma" , " Proton TOF vs TPC n#sigma (MC reco, after cuts)" , kTH2F , {nSigmaTPCaxis, nSigmaTOFaxis});
374+ histos.add (" QAMC/Proton/tpcNSigmaPionContamVsPt" , " Proton track: TPC n#sigma pion contamination (MC reco)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
375+ histos.add (" QAMC/Proton/tpcNSigmaKaonContamVsPt" , " Proton track: TPC n#sigma kaon contamination (MC reco)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
376+ histos.add (" QAMC/Proton/tofNSigmaPionContamVsMomentum" , " Proton track: TOF n#sigma pion contamination (MC reco)" , kTH2F , {momentumAxis, nSigmaTOFaxis});
377+ histos.add (" QAMC/Proton/tpcCrossedRowsVsPt" , " Proton TPC crossed rows vs p_{T} (MC reco)" , kTH2F , {ptForPIDAxis, tpcRowsAxis});
378+ histos.add (" QAMC/Proton/tpcClustersFoundVsPt" , " Proton TPC clusters found vs p_{T} (MC reco)" , kTH2F , {ptForPIDAxis, tpcClusAxis});
379+ histos.add (" QAMC/Proton/dcaXYdist" , " Proton DCA_{xy} distribution (MC reco, fine bins)" , kTH1F , {dcaXYaxis});
380+ histos.add (" QAMC/Proton/dcaZdist" , " Proton DCA_{z} distribution (MC reco, fine bins)" , kTH1F , {dcaZaxis});
381+
382+ histos.add (" QAMC/Pion/dcaXYvsPt" , " Pion DCA_{xy} vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, dcaXYaxis});
383+ histos.add (" QAMC/Pion/dcaZvsPt" , " Pion DCA_{z} vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, dcaZaxis});
384+ histos.add (" QAMC/Pion/tpcNSigmaVsMomentum" , " Pion TPC n#sigma vs p (MC reco, after cuts)" , kTH2F , {momentumAxis, nSigmaTPCaxis});
385+ histos.add (" QAMC/Pion/tpcNSigmaVsPt" , " Pion TPC n#sigma vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
386+ histos.add (" QAMC/Pion/tpcNSigmaVsCentrality" , " Pion TPC n#sigma vs centrality (MC reco)" , kTH2F , {centAxis, nSigmaTPCaxis});
387+ histos.add (" QAMC/Pion/tofNSigmaVsMomentum" , " Pion TOF n#sigma vs p (MC reco, after cuts)" , kTH2F , {momentumAxis, nSigmaTOFaxis});
388+ histos.add (" QAMC/Pion/tofNSigmaVsPt" , " Pion TOF n#sigma vs p_{T} (MC reco, after cuts)" , kTH2F , {ptForPIDAxis, nSigmaTOFaxis});
389+ histos.add (" QAMC/Pion/tofNSigmaVsCentrality" , " Pion TOF n#sigma vs centrality (MC reco)" , kTH2F , {centAxis, nSigmaTOFaxis});
390+ histos.add (" QAMC/Pion/tofNSigmaVsTPCNSigma" , " Pion TOF vs TPC n#sigma (MC reco, after cuts)" , kTH2F , {nSigmaTPCaxis, nSigmaTOFaxis});
391+ histos.add (" QAMC/Pion/tpcNSigmaProtonContamVsPt" , " Pion track: TPC n#sigma proton contamination (MC reco)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
392+ histos.add (" QAMC/Pion/tpcNSigmaKaonContamVsPt" , " Pion track: TPC n#sigma kaon contamination (MC reco)" , kTH2F , {ptForPIDAxis, nSigmaTPCaxis});
393+ histos.add (" QAMC/Pion/tofNSigmaProtonContamVsMomentum" , " Pion track: TOF n#sigma proton contamination (MC reco)" , kTH2F , {momentumAxis, nSigmaTOFaxis});
394+ histos.add (" QAMC/Pion/tpcCrossedRowsVsPt" , " Pion TPC crossed rows vs p_{T} (MC reco)" , kTH2F , {ptForPIDAxis, tpcRowsAxis});
395+ histos.add (" QAMC/Pion/tpcClustersFoundVsPt" , " Pion TPC clusters found vs p_{T} (MC reco)" , kTH2F , {ptForPIDAxis, tpcClusAxis});
396+ histos.add (" QAMC/Pion/dcaXYdist" , " Pion DCA_{xy} distribution (MC reco, fine bins)" , kTH1F , {dcaXYaxis});
397+ histos.add (" QAMC/Pion/dcaZdist" , " Pion DCA_{z} distribution (MC reco, fine bins)" , kTH1F , {dcaZaxis});
352398 }
353399 } // end init()
354400
@@ -647,6 +693,59 @@ struct DeltaAnalysis {
647693 }
648694 }
649695
696+ // detector QA for reconstructed MC tracks, no truth matching required ──
697+ template <typename TrackType>
698+ void fillQAMCProton (TrackType const & track, float totalMomentum, float centralityPercent)
699+ {
700+ const float pt = track.pt ();
701+ const float tpcNSigPr = track.tpcNSigmaPr ();
702+ histos.fill (HIST (" QAMC/Proton/dcaXYvsPt" ), pt, track.dcaXY ());
703+ histos.fill (HIST (" QAMC/Proton/dcaZvsPt" ), pt, track.dcaZ ());
704+ histos.fill (HIST (" QAMC/Proton/dcaXYdist" ), track.dcaXY ());
705+ histos.fill (HIST (" QAMC/Proton/dcaZdist" ), track.dcaZ ());
706+ histos.fill (HIST (" QAMC/Proton/tpcNSigmaVsMomentum" ), totalMomentum, tpcNSigPr);
707+ histos.fill (HIST (" QAMC/Proton/tpcNSigmaVsPt" ), pt, tpcNSigPr);
708+ histos.fill (HIST (" QAMC/Proton/tpcNSigmaVsCentrality" ), centralityPercent, tpcNSigPr);
709+ histos.fill (HIST (" QAMC/Proton/tpcNSigmaPionContamVsPt" ), pt, track.tpcNSigmaPi ());
710+ histos.fill (HIST (" QAMC/Proton/tpcNSigmaKaonContamVsPt" ), pt, track.tpcNSigmaKa ());
711+ histos.fill (HIST (" QAMC/Proton/tpcCrossedRowsVsPt" ), pt, track.tpcNClsCrossedRows ());
712+ histos.fill (HIST (" QAMC/Proton/tpcClustersFoundVsPt" ), pt, track.tpcNClsFound ());
713+ if (!useTPCOnlyPID && track.hasTOF ()) {
714+ const float tofNSigPr = track.tofNSigmaPr ();
715+ histos.fill (HIST (" QAMC/Proton/tofNSigmaVsMomentum" ), totalMomentum, tofNSigPr);
716+ histos.fill (HIST (" QAMC/Proton/tofNSigmaVsPt" ), pt, tofNSigPr);
717+ histos.fill (HIST (" QAMC/Proton/tofNSigmaVsCentrality" ), centralityPercent, tofNSigPr);
718+ histos.fill (HIST (" QAMC/Proton/tofNSigmaVsTPCNSigma" ), tpcNSigPr, tofNSigPr);
719+ histos.fill (HIST (" QAMC/Proton/tofNSigmaPionContamVsMomentum" ), totalMomentum, track.tofNSigmaPi ());
720+ }
721+ }
722+
723+ template <typename TrackType>
724+ void fillQAMCPion (TrackType const & track, float totalMomentum, float centralityPercent)
725+ {
726+ const float pt = track.pt ();
727+ const float tpcNSigPi = track.tpcNSigmaPi ();
728+ histos.fill (HIST (" QAMC/Pion/dcaXYvsPt" ), pt, track.dcaXY ());
729+ histos.fill (HIST (" QAMC/Pion/dcaZvsPt" ), pt, track.dcaZ ());
730+ histos.fill (HIST (" QAMC/Pion/dcaXYdist" ), track.dcaXY ());
731+ histos.fill (HIST (" QAMC/Pion/dcaZdist" ), track.dcaZ ());
732+ histos.fill (HIST (" QAMC/Pion/tpcNSigmaVsMomentum" ), totalMomentum, tpcNSigPi);
733+ histos.fill (HIST (" QAMC/Pion/tpcNSigmaVsPt" ), pt, tpcNSigPi);
734+ histos.fill (HIST (" QAMC/Pion/tpcNSigmaVsCentrality" ), centralityPercent, tpcNSigPi);
735+ histos.fill (HIST (" QAMC/Pion/tpcNSigmaProtonContamVsPt" ), pt, track.tpcNSigmaPr ());
736+ histos.fill (HIST (" QAMC/Pion/tpcNSigmaKaonContamVsPt" ), pt, track.tpcNSigmaKa ());
737+ histos.fill (HIST (" QAMC/Pion/tpcCrossedRowsVsPt" ), pt, track.tpcNClsCrossedRows ());
738+ histos.fill (HIST (" QAMC/Pion/tpcClustersFoundVsPt" ), pt, track.tpcNClsFound ());
739+ if (!useTPCOnlyPID && track.hasTOF ()) {
740+ const float tofNSigPi = track.tofNSigmaPi ();
741+ histos.fill (HIST (" QAMC/Pion/tofNSigmaVsMomentum" ), totalMomentum, tofNSigPi);
742+ histos.fill (HIST (" QAMC/Pion/tofNSigmaVsPt" ), pt, tofNSigPi);
743+ histos.fill (HIST (" QAMC/Pion/tofNSigmaVsCentrality" ), centralityPercent, tofNSigPi);
744+ histos.fill (HIST (" QAMC/Pion/tofNSigmaVsTPCNSigma" ), tpcNSigPi, tofNSigPi);
745+ histos.fill (HIST (" QAMC/Pion/tofNSigmaProtonContamVsMomentum" ), totalMomentum, track.tofNSigmaPr ());
746+ }
747+ }
748+
650749 void fillDeltaHistogramSameEvent (int protonSign, int pionSign, float pairPt, float pairMass, float centrality, float rapidity)
651750 {
652751 if (protonSign > 0 ) {
@@ -710,6 +809,28 @@ struct DeltaAnalysis {
710809 }
711810 }
712811
812+ // reconstructed-level (pre-truth-matching) invariant mass ──
813+ void fillDeltaHistogramMCReco (int protonSign, int pionSign, float pairPt, float pairMass, float centrality, float rapidity)
814+ {
815+ if (protonSign > 0 ) {
816+ if (pionSign > 0 ) {
817+ histos.fill (HIST (" AnalysisMCReco/hDeltaPlusPlusInvMassReco" ), pairPt, pairMass);
818+ histos.fill (HIST (" THnSparseMCReco/hDeltaPlusPlusReco" ), pairMass, pairPt, centrality, rapidity);
819+ } else {
820+ histos.fill (HIST (" AnalysisMCReco/hDeltaZeroInvMassReco" ), pairPt, pairMass);
821+ histos.fill (HIST (" THnSparseMCReco/hDeltaZeroReco" ), pairMass, pairPt, centrality, rapidity);
822+ }
823+ } else {
824+ if (pionSign < 0 ) {
825+ histos.fill (HIST (" AnalysisMCReco/hAntiDeltaPlusPlusInvMassReco" ), pairPt, pairMass);
826+ histos.fill (HIST (" THnSparseMCReco/hAntiDeltaPlusPlusReco" ), pairMass, pairPt, centrality, rapidity);
827+ } else {
828+ histos.fill (HIST (" AnalysisMCReco/hAntiDeltaZeroInvMassReco" ), pairPt, pairMass);
829+ histos.fill (HIST (" THnSparseMCReco/hAntiDeltaZeroReco" ), pairMass, pairPt, centrality, rapidity);
830+ }
831+ }
832+ }
833+
713834 void fillRotationalBackground (int protonSign, int pionSign, float pxProton, float pyProton, float pzProton, float pionPhi, float pionPt, float pzPion, float centrality)
714835 {
715836 if (numberOfRotations <= 0 )
@@ -1049,6 +1170,17 @@ struct DeltaAnalysis {
10491170 }
10501171 }
10511172
1173+ // fill QAMC for every reconstructed MC track passing basic+PID+DCA cuts, irrespective of truth matching.
1174+ for (auto const & trackForQAMC : perColTracks) {
1175+ const float momQAMC = RecoDecay::p (trackForQAMC.px (), trackForQAMC.py (), trackForQAMC.pz ());
1176+ if (!passesBasicTrackSelection (trackForQAMC))
1177+ continue ;
1178+ if (passesProtonPID (trackForQAMC, momQAMC) && passesProtonDCASelection (trackForQAMC))
1179+ fillQAMCProton (trackForQAMC, momQAMC, centrality);
1180+ if (passesPionPID (trackForQAMC, momQAMC) && passesPionDCASelection (trackForQAMC))
1181+ fillQAMCPion (trackForQAMC, momQAMC, centrality);
1182+ }
1183+
10521184 for (auto const & [t0, t1] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (perColTracks, perColTracks))) {
10531185 if (t0.globalIndex () == t1.globalIndex ())
10541186 continue ;
@@ -1060,6 +1192,20 @@ struct DeltaAnalysis {
10601192 continue ;
10611193 if (!passesProtonDCASelection (t0) || !passesPionDCASelection (t1))
10621194 continue ;
1195+
1196+ // reconstructed-level (pre-truth-matching) invariant mass.
1197+ {
1198+ const std::array<std::array<float , 3 >, 2 > momentaReco = {
1199+ std::array<float , 3 >{t0.px (), t0.py (), t0.pz ()},
1200+ std::array<float , 3 >{t1.px (), t1.py (), t1.pz ()}};
1201+ const float pairMassReco = RecoDecay::m (momentaReco, std::array{massProton, massPion});
1202+ const float pairPtReco = RecoDecay::pt (std::array{t0.px () + t1.px (), t0.py () + t1.py ()});
1203+ const float pairYReco = RecoDecay::y (std::array{t0.px () + t1.px (), t0.py () + t1.py (), t0.pz () + t1.pz ()}, pairMassReco);
1204+ if (pairYReco >= cfgMinY && pairYReco <= cfgMaxY) {
1205+ fillDeltaHistogramMCReco (t0.sign (), t1.sign (), pairPtReco, pairMassReco, centrality, pairYReco);
1206+ }
1207+ }
1208+
10631209 if (!t0.has_mcParticle () || !t1.has_mcParticle ())
10641210 continue ;
10651211 const auto mcProton = t0.mcParticle ();
@@ -1152,6 +1298,5 @@ struct DeltaAnalysis {
11521298
11531299WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
11541300{
1155- // FIX name/o2-task: TaskName is redundant when it equals the derived device name
11561301 return WorkflowSpec{adaptAnalysisTask<DeltaAnalysis>(cfgc)};
11571302}
0 commit comments