4040#include " MathUtils/BetheBlochAleph.h"
4141#include " ReconstructionDataFormats/Track.h"
4242
43+ #include " Math/Vector4D.h"
44+
4345#include < algorithm>
4446#include < array>
4547#include < memory>
4951using namespace o2 ;
5052using namespace o2 ::framework;
5153using namespace o2 ::framework::expressions;
54+ using std::array;
55+
5256using CollBracket = o2::math_utils::Bracket<int >;
5357using TracksFull = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TOFSignal, aod::TOFEvTime>;
5458using CollisionsFull = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0As, aod::CentFT0Cs, aod::CentFT0Ms>;
5559using CollisionsFullMC = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::CentFT0As, aod::CentFT0Cs, aod::CentFT0Ms>;
5660
5761using CollisionsFullWithFlow = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0As, aod::CentFT0Cs, aod::CentFT0Ms, aod::FT0Mults, aod::FV0Mults, aod::TPCMults, aod::EPCalibrationTables>;
5862
63+ using McCollisionMults = soa::Join<aod::McCollisions, aod::MultMCExtras>;
64+ using EventCandidatesMC = soa::Join<aod::Collisions, aod::EvSels, aod::McCollisionLabels, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::Mults>;
65+
5966namespace
6067{
6168constexpr double betheBlochDefault[1 ][6 ]{{-1 .e32 , -1 .e32 , -1 .e32 , -1 .e32 , -1 .e32 , -1 .e32 }};
@@ -77,6 +84,20 @@ std::shared_ptr<TH1> hH4LMassTracked;
7784std::shared_ptr<TH1> hDecayChannel;
7885std::shared_ptr<TH1> hIsMatterGen;
7986std::shared_ptr<TH1> hIsMatterGenTwoBody;
87+ std::shared_ptr<TH1> hEvtMC;
88+ std::shared_ptr<TH1> hImpactParamGen;
89+ std::shared_ptr<TH1> hImpactParamReco;
90+ std::shared_ptr<TH1> hGen3HLBeforeEvtSel;
91+ std::shared_ptr<TH1> hGen3HLAfterSel;
92+ std::shared_ptr<TH2> hRecoCentralityColvsMultiplicityRecoEta05;
93+ std::shared_ptr<TH2> hRecoCentralityColvsImpactParamReco;
94+ std::shared_ptr<TH2> hGen3HLvsImpactParameterBeforeEvtSel;
95+ std::shared_ptr<TH2> hGen3HLvsImpactParameterAfterSel;
96+ std::shared_ptr<TH2> hGen3HLvsMultiplicityGenEta05BeforeEvtSel;
97+ std::shared_ptr<TH2> hGen3HLvsMultiplicityGenEta05AfterSel;
98+ std::shared_ptr<TH2> hGen3HLvsMultiplicityFT0CBeforeEvtSel;
99+ std::shared_ptr<TH2> hGen3HLvsMultiplicityFT0CAfterSel;
100+
80101} // namespace
81102
82103struct hyperCandidate {
@@ -147,6 +168,7 @@ struct hyperRecoTask {
147168 // PDG codes
148169 Configurable<int > hyperPdg{" hyperPDG" , 1010010030 , " PDG code of the hyper-mother (could be 3LamH or 4LamH)" };
149170 Configurable<int > heDauPdg{" heDauPDG" , 1000020030 , " PDG code of the helium (could be 3He or 4He)" };
171+ Configurable<int > piDauPdg{" piDauPdg" , 211 , " PDG code of pion" };
150172
151173 // Selection criteria
152174 Configurable<double > v0cospacut{" hypcospa" , 0.95 , " V0 CosPA" };
@@ -199,6 +221,13 @@ struct hyperRecoTask {
199221 ConfigurableAxis zVtxBins{" zVtxBins" , {100 , -20 .f , 20 .f }, " Binning for n sigma" };
200222 ConfigurableAxis centBins{" centBins" , {100 , 0 .f , 100 .f }, " Binning for centrality" };
201223
224+ // histogram axes for EvtLossMC
225+ ConfigurableAxis binsImpactPar{" binsImpactPar" , {80 , 0 , 16 }, " Binning of the impact parameter axis" };
226+ ConfigurableAxis binsCent{" binsCent" , {10 , 0.0 , 100.0 }, " Binning of the centrality axis" };
227+ ConfigurableAxis binsPt{" binsPt" , {20 , 0 , 10 }, " Binning of the pt" };
228+ ConfigurableAxis binsFT0CMult{" binsFT0CMult" , {500 , 0 .0f , +500 .0f }, " Binning of the FT0C multiplicity" };
229+ ConfigurableAxis binsMult{" binsMult" , {500 , 0 .0f , +500 .0f }, " " };
230+
202231 // std vector of candidates
203232 std::vector<hyperCandidate> hyperCandidates;
204233 // vector to keep track of MC mothers already filled
@@ -219,7 +248,6 @@ struct hyperRecoTask {
219248
220249 void init (InitContext const &)
221250 {
222-
223251 zorroSummary.setObject (zorro.getZorroSummary ());
224252
225253 mRunNumber = 0 ;
@@ -250,6 +278,11 @@ struct hyperRecoTask {
250278 const AxisSpec nSigma3HeAxis{nSigmaBins, " n_{#sigma}({}^{3}He)" };
251279 const AxisSpec zVtxAxis{zVtxBins, " z_{vtx} (cm)" };
252280 const AxisSpec centAxis{centBins, " Centrality" };
281+ const AxisSpec impactParamAxis{binsImpactPar, " Impact Parameter (b)" };
282+ const AxisSpec centFT0CAxis{binsCent, " Centrality (FT0C %)" };
283+ const AxisSpec binsFT0CMultAxis {binsFT0CMult, " FT0C multiplicity" };
284+ const AxisSpec ptAxis{binsPt, " #it{p}_{T} (GeV/#it{c})" };
285+ const AxisSpec multAxis = {binsMult, " Multiplicity #eta <0.5" };
253286
254287 hNsigma3HeSel = qaRegistry.add <TH2>(" hNsigma3HeSel" , " ; p_{TPC}/z (GeV/#it{c}); n_{#sigma} ({}^{3}He)" , HistType::kTH2F , {rigidityAxis, nSigma3HeAxis});
255288 hDeDx3HeSel = qaRegistry.add <TH2>(" hDeDx3HeSel" , " ;p_{TPC}/z (GeV/#it{c}); dE/dx" , HistType::kTH2F , {rigidityAxis, dedxAxis});
@@ -259,11 +292,12 @@ struct hyperRecoTask {
259292 hH4LMassBefSel = qaRegistry.add <TH1>(" hH4LMassBefSel" , " ;M (GeV/#it{c}^{2}); " , HistType::kTH1D , {{60 , 3.76 , 3.84 }});
260293 hH4LMassTracked = qaRegistry.add <TH1>(" hH4LMassTracked" , " ;M (GeV/#it{c}^{2}); " , HistType::kTH1D , {{60 , 3.76 , 3.84 }});
261294
262- hEvents = qaRegistry.add <TH1>(" hEvents" , " ;Events; " , HistType::kTH1D , {{4 , -0.5 , 3 .5 }});
295+ hEvents = qaRegistry.add <TH1>(" hEvents" , " ;Events; " , HistType::kTH1D , {{5 , -0.5 , 4 .5 }});
263296 hEvents->GetXaxis ()->SetBinLabel (1 , " All" );
264297 hEvents->GetXaxis ()->SetBinLabel (2 , " sel8" );
265- hEvents->GetXaxis ()->SetBinLabel (3 , " kNoSameBunchPileup" );
266- hEvents->GetXaxis ()->SetBinLabel (4 , " kIsGoodZvtxFT0vsPV" );
298+ hEvents->GetXaxis ()->SetBinLabel (3 , " z_{vtx}" );
299+ hEvents->GetXaxis ()->SetBinLabel (4 , " kNoSameBunchPileup" );
300+ hEvents->GetXaxis ()->SetBinLabel (5 , " kIsGoodZvtxFT0vsPV" );
267301
268302 hEventsZorro = qaRegistry.add <TH1>(" hEventsZorro" , " ;Events; " , HistType::kTH1D , {{2 , -0.5 , 1.5 }});
269303 hEventsZorro->GetXaxis ()->SetBinLabel (1 , " Zorro before evsel" );
@@ -284,6 +318,29 @@ struct hyperRecoTask {
284318 hCentFT0A = qaRegistry.add <TH1>(" hCentFT0A" , " ;Centrality; " , HistType::kTH1D , {{100 , 0 , 100 }});
285319 hCentFT0C = qaRegistry.add <TH1>(" hCentFT0C" , " ;Centrality; " , HistType::kTH1D , {{100 , 0 , 100 }});
286320 hCentFT0M = qaRegistry.add <TH1>(" hCentFT0M" , " ;Centrality; " , HistType::kTH1D , {{100 , 0 , 100 }});
321+
322+ if (doprocessEventLossMC) {
323+ hEvtMC = qaRegistry.add <TH1>(" QAEvent/hEvtMC" , " ;; " , HistType::kTH1D , {{3 , -0.5 , 2.5 }});
324+ hEvtMC->GetXaxis ()->SetBinLabel (1 , " All gen evts" );
325+ hEvtMC->GetXaxis ()->SetBinLabel (2 , " Gen evts with al least one reconstructed" );
326+ hEvtMC->GetXaxis ()->SetBinLabel (3 , " Gen evts with no reconstructed collisions" );
327+ // Infomation for all generated collisions collisions
328+ hImpactParamGen = qaRegistry.add <TH1>(" QAEvent/McColAll/hImpactParamGen" , " Impact parameter of generated MC events; Impact Parameter (b); Counts" , HistType::kTH1D , {impactParamAxis});
329+ // Infomation for generated collisions collisions with at least one rec. event
330+ hImpactParamReco = qaRegistry.add <TH1>(" QAEvent/McColAll/hImpactParamReco" , " Impact parameter of generated MC events with at least one rec. evt; Impact Parameter (b); Counts" , HistType::kTH1D , {impactParamAxis});
331+ hRecoCentralityColvsMultiplicityRecoEta05 = qaRegistry.add <TH2>(" QAEvent/McColAll/hRecoCentralityColvsMultiplicityRecoEta05" , " Correlation between FT0C centrality and charged particle multiplicity in generated MC events with at least one rec. evt; Multiplicity #eta <0.5; Counts" , HistType::kTH2D , {centFT0CAxis, multAxis});
332+ hRecoCentralityColvsImpactParamReco = qaRegistry.add <TH2>(" QAEvent/McColAll/hRecoCentralityColvsImpactParamReco" , " Correlation between FT0C centrality and impact parameter in generated MC events with at least one rec. evt; Impact Parameter (b); Counts" , HistType::kTH2D , {centFT0CAxis, impactParamAxis});
333+ // Information of generated 3HL in generated events
334+ hGen3HLBeforeEvtSel = qaRegistry.add <TH1>(" QAEvent/McCol3HL/hGen3HLBeforeEvtSel" , " 3HL generated #it{p}_{T} distribution in all gen evt;#it{p}_{T} (GeV/#it{c}); Counts" , HistType::kTH1D , {ptAxis});
335+ hGen3HLvsImpactParameterBeforeEvtSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsImpactParameterBeforeEvtSel" , " Correlation 3HL generated #it{p}_{T} and impact parameter in all gen evt;#it{p}_{T} (GeV/#it{c}); Impact parameter (b)" , HistType::kTH2D , {ptAxis, impactParamAxis});
336+ hGen3HLvsMultiplicityGenEta05BeforeEvtSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsMultiplicityGenEta05BeforeEvtSel" , " Correlation 3HL generated #it{p}_{T} and charged particle multiplicity in all gen evt;#it{p}_{T} (GeV/#it{c}); Multiplicity #eta <0.5" , HistType::kTH2D , {ptAxis, multAxis});
337+ hGen3HLvsMultiplicityFT0CBeforeEvtSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsMultiplicityFT0CBeforeEvtSel" , " Correlation 3HL generated #it{p}_{T} and FT0C multiplicity in all gen evt;#it{p}_{T} (GeV/#it{c}); FT0C Multiplicity" , HistType::kTH2D , {ptAxis, binsFT0CMultAxis});
338+ // Information of generated 3HL in generated events with at least one rec. event
339+ hGen3HLAfterSel = qaRegistry.add <TH1>(" QAEvent/McCol3HL/hGen3HLAfterSel" , " 3HL generated #it{p}_{T} distribution in gen. evts with at least one rec. evt; #it{p}_{T} (GeV/#it{c}); Counts" , HistType::kTH1D , {ptAxis});
340+ hGen3HLvsImpactParameterAfterSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsImpactParameterAfterSel" , " Correlation 3HL generated #it{p}_{T} and impact parameter in gen. evts with at least one rec. evt;#it{p}_{T} (GeV/#it{c}); Impact parameter (b)" , HistType::kTH2D , {ptAxis, impactParamAxis});
341+ hGen3HLvsMultiplicityGenEta05AfterSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsMultiplicityGenEta05AfterSel" , " Correlation 3HL generated #it{p}_{T} and charged particle multiplicity in gen. evts with at least one rec. evt;#it{p}_{T} (GeV/#it{c}); Multiplicity #eta <0.5" , HistType::kTH2D , {ptAxis, multAxis});
342+ hGen3HLvsMultiplicityFT0CAfterSel = qaRegistry.add <TH2>(" QAEvent/McCol3HL/hGen3HLvsMultiplicityFT0CAfterSel" , " Correlation 3HL generated #it{p}_{T} and FT0C multiplicity in gen. evts with at least one rec;#it{p}_{T} (GeV/#it{c}); FT0C Multiplicity" , HistType::kTH2D , {ptAxis, binsFT0CMultAxis});
343+ }
287344 }
288345
289346 void initCCDB (aod::BCsWithTimestamps::iterator const & bc)
@@ -345,6 +402,8 @@ struct hyperRecoTask {
345402 return static_cast <float >((candidate.tpcSignal () - expTPCSignal) / resoTPC);
346403 }
347404
405+
406+
348407 template <class Tcoll >
349408 void selectGoodCollisions (const Tcoll& collisions)
350409 {
@@ -366,12 +425,18 @@ struct hyperRecoTask {
366425 }
367426 }
368427
369- if (!collision.selection_bit (aod::evsel::kIsTriggerTVX ) || !collision.selection_bit (aod::evsel::kNoTimeFrameBorder ) || std::abs (collision. posZ ()) > 10 ) {
428+ if (!collision.selection_bit (aod::evsel::kIsTriggerTVX ) || !collision.selection_bit (aod::evsel::kNoTimeFrameBorder )) {
370429 continue ;
371430 }
372431
373432 hEvents->Fill (1 .);
374433
434+ if (std::abs (collision.posZ ()) > 10 ){
435+ hEvents->Fill (2 .);
436+ continue ;
437+ }
438+
439+
375440 if (zorroSelected) {
376441 hEventsZorro->Fill (1 .);
377442 }
@@ -380,14 +445,14 @@ struct hyperRecoTask {
380445 if (!collision.selection_bit (aod::evsel::kNoSameBunchPileup )) {
381446 continue ;
382447 }
383- hEvents->Fill (2 .);
384- }
448+ hEvents->Fill (3 .);
385449
450+ }
386451 if (cfgEvSelkIsGoodZvtxFT0vsPV) {
387452 if (!collision.selection_bit (aod::evsel::kIsGoodZvtxFT0vsPV )) {
388453 continue ;
389454 }
390- hEvents->Fill (3 .);
455+ hEvents->Fill (4 .);
391456 }
392457
393458 goodCollision[collision.globalIndex ()] = true ;
@@ -408,23 +473,27 @@ struct hyperRecoTask {
408473 if (collision.has_mcCollision ()) {
409474 recoCollisionIds[collision.mcCollisionId ()] = collision.globalIndex ();
410475 }
411- if (!collision.selection_bit (aod::evsel::kIsTriggerTVX ) || !collision.selection_bit (aod::evsel::kNoTimeFrameBorder ) || std::abs (collision. posZ ()) > 10 )
476+ if (!collision.selection_bit (aod::evsel::kIsTriggerTVX ) || !collision.selection_bit (aod::evsel::kNoTimeFrameBorder ))
412477 continue ;
413-
478+
414479 hEvents->Fill (1 .);
415480
481+ if (std::abs (collision.posZ ()) > 10 ){
482+ hEvents->Fill (2 .);
483+ continue ;
484+ }
485+
416486 if (cfgEvSelkNoSameBunchPileup) {
417487 if (!collision.selection_bit (aod::evsel::kNoSameBunchPileup )) {
418488 continue ;
419489 }
420- hEvents->Fill (2 .);
421- }
422-
490+ hEvents->Fill (3 .);
491+ }
423492 if (cfgEvSelkIsGoodZvtxFT0vsPV) {
424493 if (!collision.selection_bit (aod::evsel::kIsGoodZvtxFT0vsPV )) {
425494 continue ;
426495 }
427- hEvents->Fill (3 .);
496+ hEvents->Fill (4 .);
428497 }
429498
430499 if (collision.has_mcCollision ()) {
@@ -435,9 +504,9 @@ struct hyperRecoTask {
435504 hCentFT0A->Fill (collision.centFT0A ());
436505 hCentFT0C->Fill (collision.centFT0C ());
437506 hCentFT0M->Fill (collision.centFT0M ());
507+
438508 }
439509 }
440-
441510 template <class Ttrack , class Tcolls >
442511 void fillHyperCand (Ttrack& heTrack, Ttrack& piTrack, CollBracket collBracket, const Tcolls& collisions, hyperCandidate& hypCand)
443512 {
@@ -922,6 +991,114 @@ struct hyperRecoTask {
922991 processMC (collisions, mcCollisions, V0s, tracks, ambiTracks, bcs, trackLabelsMC, particlesMC);
923992 }
924993 PROCESS_SWITCH (hyperRecoTask, processMCTracked, " MC analysis with tracked V0s" , false );
994+
995+ template <typename CollType>
996+ bool passEvtSel (const CollType& collision)
997+ {
998+ if (!collision.sel8 ())
999+ return false ;
1000+
1001+ if ((std::abs (collision.posZ ())) > 10 )
1002+ return false ;
1003+
1004+ if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit (aod::evsel::kNoSameBunchPileup ))
1005+ return false ;
1006+
1007+ if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV ))
1008+ return false ;
1009+
1010+ return true ;
1011+ }
1012+
1013+ void processEventLossMC (McCollisionMults::iterator const & mcCollision, soa::SmallGroups<EventCandidatesMC> const & collisions, aod::McParticles const & GenParticles)
1014+ {
1015+ if (std::abs (mcCollision.posZ ()) > 10 ) {
1016+ return ;
1017+ }
1018+
1019+ // ////////// Event loss estimation via impact parameter and multiplicity by MCFT0C
1020+
1021+ // Fill all generated events
1022+ hEvtMC->Fill (0 );
1023+ hImpactParamGen->Fill (mcCollision.impactParameter ());
1024+
1025+ // Fill generated events with no reconstructed collisions
1026+ if (collisions.size () == 0 ) {
1027+ hEvtMC->Fill (1 );
1028+ }
1029+
1030+ // Define the generated events with at least one reconstructed event
1031+ bool atLeastOneRecoEvt = false ;
1032+ auto centralityFT0C = -999 .;
1033+
1034+ for (auto const & col : collisions) {
1035+ if (!passEvtSel (col)) {
1036+ continue ;
1037+ }
1038+ centralityFT0C = col.centFT0C ();
1039+ atLeastOneRecoEvt = true ;
1040+ }
1041+
1042+ if (atLeastOneRecoEvt) {
1043+ hEvtMC->Fill (2 );
1044+ hImpactParamReco->Fill (mcCollision.impactParameter ());
1045+ hRecoCentralityColvsMultiplicityRecoEta05->Fill (centralityFT0C, mcCollision.multMCNParticlesEta05 ());
1046+ hRecoCentralityColvsImpactParamReco->Fill (centralityFT0C, mcCollision.impactParameter ());
1047+ }
1048+ // Construct the H3L 4-vector based on the generated daugthers identification by PDG
1049+ ROOT::Math::PxPyPzMVector daugh1, daugh2, mother;
1050+
1051+ for (const auto & genParticle : GenParticles) {
1052+ if (std::abs (genParticle.y ()) > 1 )
1053+ continue ;
1054+ if (std::abs (genParticle.pdgCode ()) != hyperPdg)
1055+ continue ;
1056+
1057+ auto daughters = genParticle.daughters_as <aod::McParticles>();
1058+
1059+ bool dauHe3 = false , dauPiMinus = false , dauAntiHe3 = false , dauPiPos = true ;
1060+
1061+ for (const auto & daughter : daughters) {
1062+ if (daughter.pdgCode () == heDauPdg) {
1063+ dauHe3 = true ;
1064+ daugh1 = ROOT::Math::PxPyPzMVector (daughter.px (), daughter.py (), daughter.pz (), he3Mass);
1065+ }
1066+ else if (daughter.pdgCode () == -piDauPdg) {
1067+ dauPiMinus = true ;
1068+ daugh2 = ROOT::Math::PxPyPzMVector (daughter.px (), daughter.py (), daughter.pz (), piMass);
1069+ }
1070+ if (daughter.pdgCode () == -heDauPdg) {
1071+ dauAntiHe3 = true ;
1072+ daugh1 = ROOT::Math::PxPyPzMVector (daughter.px (), daughter.py (), daughter.pz (), he3Mass);
1073+ }
1074+ else if (daughter.pdgCode () == piDauPdg) {
1075+ dauPiPos = true ;
1076+ daugh2 = ROOT::Math::PxPyPzMVector (daughter.px (), daughter.py (), daughter.pz (), piMass);
1077+ }
1078+ }
1079+ // Check pairs to avoid wrong charge associations
1080+ if (!((dauHe3 && dauPiMinus) || !(dauAntiHe3 && dauPiPos)))
1081+ continue ;
1082+
1083+ mother = daugh1 + daugh2;
1084+
1085+ // Fill informations for generated 3HL in all generated events
1086+ hGen3HLBeforeEvtSel->Fill (mother.pt ());
1087+ hGen3HLvsImpactParameterBeforeEvtSel->Fill (mother.pt (), mcCollision.impactParameter ());
1088+ hGen3HLvsMultiplicityGenEta05BeforeEvtSel->Fill (mother.pt (), mcCollision.multMCNParticlesEta05 ());
1089+ hGen3HLvsMultiplicityFT0CBeforeEvtSel->Fill (mother.pt (), mcCollision.multMCFT0C ());
1090+
1091+ // Fill informations for generated 3HL in generated events with at least one reconstructed event
1092+ if (atLeastOneRecoEvt) {
1093+ hGen3HLAfterSel->Fill (mother.pt ());
1094+ hGen3HLvsImpactParameterAfterSel->Fill (mother.pt (), mcCollision.impactParameter ());
1095+ hGen3HLvsMultiplicityGenEta05AfterSel->Fill (mother.pt (), mcCollision.multMCNParticlesEta05 ());
1096+ hGen3HLvsMultiplicityFT0CAfterSel->Fill (mother.pt (), mcCollision.multMCFT0C ());
1097+ }
1098+ }
1099+ }
1100+ PROCESS_SWITCH (hyperRecoTask, processEventLossMC, " Event loss analysis" , false );
1101+
9251102};
9261103
9271104WorkflowSpec
0 commit comments