@@ -66,6 +66,9 @@ struct HfTaskLc {
6666 Configurable<bool > storeOccupancy{" storeOccupancy" , true , " Flag to store occupancy information" };
6767 Configurable<int > occEstimator{" occEstimator" , 2 , " Occupancy estimation (None: 0, ITS: 1, FT0C: 2)" };
6868
69+ constexpr static float CtToProperLifetimePs = 1 .f / o2::constants::physics::LightSpeedCm2PS;
70+ constexpr static float NanoToPico = 1000 .f;
71+
6972 HfHelper hfHelper;
7073 SliceCache cache;
7174
@@ -100,6 +103,7 @@ struct HfTaskLc {
100103 ConfigurableAxis thnConfigAxisGenPtB{" thnConfigAxisGenPtB" , {1000 , 0 , 100 }, " Gen Pt B" };
101104 ConfigurableAxis thnConfigAxisNumPvContr{" thnConfigAxisNumPvContr" , {200 , -0.5 , 199.5 }, " Number of PV contributors" };
102105 ConfigurableAxis thnConfigAxisOccupancy{" thnConfigAxisOccupancy" , {14 , 0 , 14000 }, " axis for centrality" };
106+ ConfigurableAxis thnConfigAxisProperLifetime{" thnConfigAxisProperLifetime" , {200 , 0 , 2 }, " Proper lifetime, ps" };
103107
104108 HistogramRegistry registry{
105109 " registry" ,
@@ -317,6 +321,7 @@ struct HfTaskLc {
317321 const AxisSpec thnAxisPtB{thnConfigAxisGenPtB, " #it{p}_{T}^{B} (GeV/#it{c})" };
318322 const AxisSpec thnAxisTracklets{thnConfigAxisNumPvContr, " Number of PV contributors" };
319323 const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, " Occupancy" };
324+ const AxisSpec thnAxisProperLifetime{thnConfigAxisProperLifetime, " T_{proper} (ps)" };
320325
321326 bool isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M;
322327 bool isMcWithMl = doprocessMcWithMl || doprocessMcWithMlWithFT0C || doprocessMcWithMlWithFT0M;
@@ -332,13 +337,13 @@ struct HfTaskLc {
332337 axesStd = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
333338 }
334339 if (isMcStd || isMcWithMl) {
335- axesGen = {thnAxisPt, thnAxisCentrality, thnAxisY, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
340+ axesGen = {thnAxisPt, thnAxisCentrality, thnAxisY, thnAxisTracklets, thnAxisPtB, thnAxisCanType, thnAxisProperLifetime };
336341 }
337342 if (isDataWithMl) {
338- axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets};
343+ axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisProperLifetime };
339344 }
340345 if (isMcWithMl) {
341- axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
346+ axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisPtB, thnAxisCanType, thnAxisProperLifetime };
342347 }
343348
344349 if (storeOccupancy) {
@@ -542,6 +547,7 @@ struct HfTaskLc {
542547 }
543548 double massLc (-1 );
544549 double outputBkg (-1 ), outputPrompt (-1 ), outputFD (-1 );
550+ const float properLifetime = hfHelper.ctLc (candidate) * CtToProperLifetimePs;
545551 if ((candidate.isSelLcToPKPi () >= selectionFlagLc) && pdgCodeProng0 == kProton ) {
546552 massLc = hfHelper.invMassLcToPKPi (candidate);
547553
@@ -553,9 +559,9 @@ struct HfTaskLc {
553559 }
554560 // / Fill the ML outputScores and variables of candidate
555561 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
556- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, occ);
562+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, properLifetime, occ);
557563 } else {
558- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType);
564+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, properLifetime );
559565 }
560566
561567 } else {
@@ -580,10 +586,10 @@ struct HfTaskLc {
580586 }
581587 // / Fill the ML outputScores and variables of candidate (todo: add multiplicity)
582588 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
583- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, occ);
589+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, properLifetime, occ);
584590
585591 } else {
586- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType);
592+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, ptRecB, originType, properLifetime );
587593 }
588594 } else {
589595 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
@@ -624,6 +630,11 @@ struct HfTaskLc {
624630 occ = o2::hf_occupancy::getOccupancyGenColl (recoCollsPerMcColl, occEstimator);
625631 }
626632
633+ const auto mcDaughter0 = particle.template daughters_as <soa::Join<aod::McParticles, aod::HfCand3ProngMcGen>>().begin ();
634+ const float p2m = particle.p () / o2::constants::physics::MassLambdaCPlus;
635+ const float gamma = std::sqrt (1 + p2m * p2m); // mother's particle Lorentz factor
636+ const float properLifetime = mcDaughter0.vt () * NanoToPico / gamma; // from ns to ps * from lab time to proper time
637+
627638 registry.fill (HIST (" MC/generated/signal/hPtGen" ), ptGen);
628639 registry.fill (HIST (" MC/generated/signal/hEtaGen" ), particle.eta ());
629640 registry.fill (HIST (" MC/generated/signal/hYGen" ), yGen);
@@ -635,10 +646,10 @@ struct HfTaskLc {
635646 if (particle.originMcGen () == RecoDecay::OriginType::Prompt) {
636647 if (fillTHn) {
637648 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
638- registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, occ);
649+ registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, properLifetime, occ);
639650
640651 } else {
641- registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType);
652+ registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, properLifetime );
642653 }
643654 }
644655 registry.fill (HIST (" MC/generated/prompt/hPtGenPrompt" ), ptGen);
@@ -653,10 +664,10 @@ struct HfTaskLc {
653664 ptGenB = mcParticles.rawIteratorAt (particle.idxBhadMotherPart ()).pt ();
654665 if (fillTHn) {
655666 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
656- registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, occ);
667+ registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, properLifetime, occ);
657668
658669 } else {
659- registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType);
670+ registry.get <THnSparse>(HIST (" hnLcVarsGen" ))->Fill (ptGen, cent, yGen, numPvContributors, ptGenB, originType, properLifetime );
660671 }
661672 }
662673 registry.fill (HIST (" MC/generated/nonprompt/hPtGenNonPrompt" ), ptGen);
@@ -748,6 +759,7 @@ struct HfTaskLc {
748759 }
749760 double massLc (-1 );
750761 double outputBkg (-1 ), outputPrompt (-1 ), outputFD (-1 );
762+ const float properLifetime = hfHelper.ctLc (candidate) * CtToProperLifetimePs;
751763 if (candidate.isSelLcToPKPi () >= selectionFlagLc) {
752764 massLc = hfHelper.invMassLcToPKPi (candidate);
753765
@@ -759,10 +771,10 @@ struct HfTaskLc {
759771 }
760772 // / Fill the ML outputScores and variables of candidate
761773 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
762- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, occ);
774+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, properLifetime, occ);
763775
764776 } else {
765- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors);
777+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, properLifetime );
766778 }
767779 } else {
768780 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
@@ -785,9 +797,9 @@ struct HfTaskLc {
785797 }
786798 // / Fill the ML outputScores and variables of candidate
787799 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
788- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, occ);
800+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, properLifetime, occ);
789801 } else {
790- registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors);
802+ registry.get <THnSparse>(HIST (" hnLcVarsWithBdt" ))->Fill (massLc, pt, cent, outputBkg, outputPrompt, outputFD, numPvContributors, properLifetime );
791803 }
792804 } else {
793805 if (storeOccupancy && occEstimator != o2::hf_occupancy::OccupancyEstimator::None) {
0 commit comments