@@ -151,6 +151,10 @@ struct qaMatching {
151151 Configurable<std::string> fConfigGrpMagPath {" grpmagPath-" , " GLO/Config/GRPMagField" , " CCDB path of the GRPMagField object" };
152152 } fConfigCCDB ;
153153
154+ struct : ConfigurableGroup {
155+ Configurable<bool > fCreatePdgMomHistograms {" cfgCreatePdgMomHistograms" , false , " create matching characteristics plots with particle mom PDG codes" };
156+ } fConfigQAs ;
157+
154158 // / Variables for histograms configuration
155159 Configurable<int > fNCandidatesMax {" nCandidatesMax" , 5 , " " };
156160
@@ -297,20 +301,29 @@ struct qaMatching {
297301 struct EfficiencyPlotter {
298302 o2::framework::HistPtr p_num;
299303 o2::framework::HistPtr p_den;
304+ o2::framework::HistPtr p_pdg_num;
305+ o2::framework::HistPtr p_pdg_den;
300306 o2::framework::HistPtr pt_num;
301307 o2::framework::HistPtr pt_den;
308+ o2::framework::HistPtr pt_pdg_num;
309+ o2::framework::HistPtr pt_pdg_den;
302310 o2::framework::HistPtr phi_num;
303311 o2::framework::HistPtr phi_den;
312+ o2::framework::HistPtr phi_pdg_num;
313+ o2::framework::HistPtr phi_pdg_den;
304314 o2::framework::HistPtr eta_num;
305315 o2::framework::HistPtr eta_den;
316+ o2::framework::HistPtr eta_pdg_num;
317+ o2::framework::HistPtr eta_pdg_den;
306318
307319 EfficiencyPlotter (std::string path, std::string title,
308- HistogramRegistry& registry)
320+ HistogramRegistry& registry, bool createPdgMomHistograms )
309321 {
310322 AxisSpec pAxis = {100 , 0 , 100 , " p (GeV/c)" };
311323 AxisSpec pTAxis = {100 , 0 , 10 , " p_{T} (GeV/c)" };
312324 AxisSpec etaAxis = {100 , -4 , -2 , " #eta" };
313325 AxisSpec phiAxis = {90 , -180 , 180 , " #phi (degrees)" };
326+ AxisSpec motherPDGAxis{1201 , -600.5 , 600.5 , " Direct mother PDG" };
314327
315328 std::string histName;
316329 std::string histTitle;
@@ -324,6 +337,16 @@ struct qaMatching {
324337 histTitle = title + " vs. p - den" ;
325338 p_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH1F , {pAxis}});
326339
340+ if (createPdgMomHistograms) {
341+ histName = path + " p_pdg_num" ;
342+ histTitle = title + " vs. p vs pdg ID - num" ;
343+ p_pdg_num = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {pAxis, motherPDGAxis}});
344+
345+ histName = path + " p_pdg_den" ;
346+ histTitle = title + " vs. p vs pdg ID - den" ;
347+ p_pdg_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {pAxis, motherPDGAxis}});
348+ }
349+
327350 // pT dependence
328351 histName = path + " pt_num" ;
329352 histTitle = title + " vs. p_{T} - num" ;
@@ -333,6 +356,16 @@ struct qaMatching {
333356 histTitle = title + " vs. p_{T} - den" ;
334357 pt_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH1F , {pTAxis}});
335358
359+ if (createPdgMomHistograms) {
360+ histName = path + " pt_pdg_num" ;
361+ histTitle = title + " vs. p_{T} vs pdg ID - num" ;
362+ pt_pdg_num = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {pTAxis, motherPDGAxis}});
363+
364+ histName = path + " pt_pdg_den" ;
365+ histTitle = title + " vs. p_{T} vs pdg ID - den" ;
366+ pt_pdg_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {pTAxis, motherPDGAxis}});
367+ }
368+
336369 // eta dependence
337370 histName = path + " eta_num" ;
338371 histTitle = title + " vs. #eta - num" ;
@@ -342,6 +375,16 @@ struct qaMatching {
342375 histTitle = title + " vs. #eta - den" ;
343376 eta_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH1F , {etaAxis}});
344377
378+ if (createPdgMomHistograms) {
379+ histName = path + " eta_pdg_num" ;
380+ histTitle = title + " vs. #eta vs pdg ID - num" ;
381+ eta_pdg_num = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {etaAxis, motherPDGAxis}});
382+
383+ histName = path + " eta_pdg_den" ;
384+ histTitle = title + " vs. #eta vs pdg ID - den" ;
385+ eta_pdg_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {etaAxis, motherPDGAxis}});
386+ }
387+
345388 // phi dependence
346389 histName = path + " phi_num" ;
347390 histTitle = title + " vs. #phi - num" ;
@@ -350,6 +393,16 @@ struct qaMatching {
350393 histName = path + " phi_den" ;
351394 histTitle = title + " vs. #phi - den" ;
352395 phi_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH1F , {phiAxis}});
396+
397+ if (createPdgMomHistograms) {
398+ histName = path + " phi_pdg_num" ;
399+ histTitle = title + " vs. #phi vs pdg ID - num" ;
400+ phi_pdg_num = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {phiAxis, motherPDGAxis}});
401+
402+ histName = path + " phi_pdg_den" ;
403+ histTitle = title + " vs. #phi vs pdg ID - den" ;
404+ phi_pdg_den = registry.add (histName.c_str (), histTitle.c_str (), {HistType::kTH2F , {phiAxis, motherPDGAxis}});
405+ }
353406 }
354407
355408 template <class T >
@@ -368,6 +421,24 @@ struct qaMatching {
368421 std::get<std::shared_ptr<TH1>>(phi_num)->Fill (phi);
369422 }
370423 }
424+
425+ // Study the PDG origin of particles and their effect on the purity score
426+ template <class T >
427+ void Fill (const T& track, int pdgCode, bool passed)
428+ {
429+ double phi = track.phi () * 180 / TMath::Pi ();
430+ std::get<std::shared_ptr<TH2>>(p_pdg_den)->Fill (track.p (), pdgCode);
431+ std::get<std::shared_ptr<TH2>>(pt_pdg_den)->Fill (track.pt (), pdgCode);
432+ std::get<std::shared_ptr<TH2>>(eta_pdg_den)->Fill (track.eta (), pdgCode);
433+ std::get<std::shared_ptr<TH2>>(phi_pdg_den)->Fill (phi, pdgCode);
434+
435+ if (passed) {
436+ std::get<std::shared_ptr<TH2>>(p_pdg_num)->Fill (track.p (), pdgCode);
437+ std::get<std::shared_ptr<TH2>>(pt_pdg_num)->Fill (track.pt (), pdgCode);
438+ std::get<std::shared_ptr<TH2>>(eta_pdg_num)->Fill (track.eta (), pdgCode);
439+ std::get<std::shared_ptr<TH2>>(phi_pdg_num)->Fill (phi, pdgCode);
440+ }
441+ }
371442 };
372443
373444 struct MatchRankingHistos {
@@ -458,11 +529,11 @@ struct qaMatching {
458529 HistogramRegistry* registry;
459530
460531 MatchingPlotter (std::string path,
461- HistogramRegistry* reg)
462- : fMatchingPurityPlotter (path + " matching-purity/" , " Matching purity" , *reg),
463- fPairingEfficiencyPlotter (path + " pairing-efficiency/" , " Pairing efficiency" , *reg),
464- fMatchingEfficiencyPlotter(path + " matching-efficiency/" , " Matching efficiency" , *reg),
465- fFakeMatchingEfficiencyPlotter(path + " fake-matching-efficiency/" , " Fake matching efficiency" , *reg)
532+ HistogramRegistry* reg, bool createPdgMomHistograms )
533+ : fMatchingPurityPlotter (path + " matching-purity/" , " Matching purity" , *reg, createPdgMomHistograms ),
534+ fPairingEfficiencyPlotter (path + " pairing-efficiency/" , " Pairing efficiency" , *reg, createPdgMomHistograms ),
535+ fMatchingEfficiencyPlotter(path + " matching-efficiency/" , " Matching efficiency" , *reg, createPdgMomHistograms ),
536+ fFakeMatchingEfficiencyPlotter(path + " fake-matching-efficiency/" , " Fake matching efficiency" , *reg, createPdgMomHistograms )
466537 {
467538 registry = reg;
468539 AxisSpec pAxis = {100 , 0 , 100 , " p (GeV/c)" };
@@ -688,19 +759,19 @@ struct qaMatching {
688759 registry.add ((histPath + " selectedMCHTracksAtMFTTrue" ).c_str (), " Selected MCH tracks position at MFT end - true" , {HistType::kTH2F , {trackPositionXAtMFTAxis, trackPositionYAtMFTAxis}});
689760 registry.add ((histPath + " selectedMCHTracksAtMFTFake" ).c_str (), " Selected MCH tracks position at MFT end - fake" , {HistType::kTH2F , {trackPositionXAtMFTAxis, trackPositionYAtMFTAxis}});
690761
691- fChi2MatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Prod/" , ®istryMatching);
762+ fChi2MatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Prod/" , ®istryMatching, fConfigQAs . fCreatePdgMomHistograms );
692763 int registryIndex = 0 ;
693764 for (const auto & [label, func] : matchingChi2Functions) {
694- fMatchingPlotters [label] = std::make_unique<MatchingPlotter>(histPath + label + " /" , registryMatchingVec[registryIndex]);
765+ fMatchingPlotters [label] = std::make_unique<MatchingPlotter>(histPath + label + " /" , registryMatchingVec[registryIndex], fConfigQAs . fCreatePdgMomHistograms );
695766 registryIndex += 1 ;
696767 }
697768 for (const auto & [label, response] : matchingMlResponses) {
698- fMatchingPlotters [label] = std::make_unique<MatchingPlotter>(histPath + label + " /" , (registryMatchingVec[registryIndex]));
769+ fMatchingPlotters [label] = std::make_unique<MatchingPlotter>(histPath + label + " /" , (registryMatchingVec[registryIndex]), fConfigQAs . fCreatePdgMomHistograms );
699770 registryIndex += 1 ;
700771 }
701772
702- fTaggedMuonsMatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Tagged/" , ®istryMatching);
703- fSelectedMuonsMatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Selected/" , ®istryMatching);
773+ fTaggedMuonsMatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Tagged/" , ®istryMatching, fConfigQAs . fCreatePdgMomHistograms );
774+ fSelectedMuonsMatchingPlotter = std::make_unique<MatchingPlotter>(histPath + " Selected/" , ®istryMatching, fConfigQAs . fCreatePdgMomHistograms );
704775 }
705776
706777 void CreateDimuonHistos ()
@@ -2066,10 +2137,26 @@ struct qaMatching {
20662137 // check if the matching candidate is a true one
20672138 bool isTrueMatch = IsTrueGlobalMatching (muonTrack, matchablePairs);
20682139
2069- if (verbose)
2140+ // ---- MC ancestry ----
2141+ auto motherParticles = GetMotherParticles (muonTrack);
2142+ int motherPDG = 0 ;
2143+ if (motherParticles.size () > 1 ) {
2144+ motherPDG = motherParticles[1 ].first ;
2145+ }
2146+
2147+ if (verbose) {
20702148 std::cout << std::format (" MCH track #{} -> Muon track #{}, isTrueMatch={}" , mchIndex, globalTracksVector[0 ].globalTrackId , isTrueMatch) << std::endl;
2149+ std::cout << " MC ancestry (pdg): " ;
2150+ for (auto const & [pdg, idx] : motherParticles) {
2151+ std::cout << " (" << pdg << " ) " ;
2152+ }
2153+ std::cout << std::endl;
2154+ }
20712155 // fill matching purity plots
20722156 plotter->fMatchingPurityPlotter .Fill (mchTrack, isTrueMatch);
2157+ if (fConfigQAs .fCreatePdgMomHistograms ) {
2158+ plotter->fMatchingPurityPlotter .Fill (mchTrack, motherPDG, isTrueMatch);
2159+ }
20732160 }
20742161
20752162 // ====================================
@@ -2105,10 +2192,34 @@ struct qaMatching {
21052192 }
21062193 }
21072194
2195+ // ---- MC ancestry ----
2196+ auto motherParticles = GetMotherParticles (mchTrack);
2197+ int motherPDG = 0 ;
2198+ if (motherParticles.size () > 1 ) {
2199+ motherPDG = motherParticles[1 ].first ;
2200+ }
2201+
2202+ if (verbose) {
2203+ std::cout << " MC ancestry (pdg): " ;
2204+ for (auto const & [pdg, idx] : motherParticles) {
2205+ std::cout << " (" << pdg << " ) " ;
2206+ }
2207+ std::cout << std::endl;
2208+ }
2209+
21082210 // fill matching efficiency plots
21092211 plotter->fPairingEfficiencyPlotter .Fill (mchTrack, goodMatchFound);
2212+ if (fConfigQAs .fCreatePdgMomHistograms ) {
2213+ plotter->fPairingEfficiencyPlotter .Fill (mchTrack, motherPDG, goodMatchFound);
2214+ }
21102215 plotter->fMatchingEfficiencyPlotter .Fill (mchTrack, (goodMatchFound && isTrueMatch));
2216+ if (fConfigQAs .fCreatePdgMomHistograms ) {
2217+ plotter->fMatchingEfficiencyPlotter .Fill (mchTrack, motherPDG, (goodMatchFound && isTrueMatch));
2218+ }
21112219 plotter->fFakeMatchingEfficiencyPlotter .Fill (mchTrack, (goodMatchFound && !isTrueMatch));
2220+ if (fConfigQAs .fCreatePdgMomHistograms ) {
2221+ plotter->fFakeMatchingEfficiencyPlotter .Fill (mchTrack, motherPDG, (goodMatchFound && !isTrueMatch));
2222+ }
21122223 }
21132224 }
21142225
0 commit comments