@@ -71,8 +71,8 @@ using namespace o2::framework;
7171using namespace o2 ::framework::expressions;
7272using namespace constants ::math;
7373
74- #define O2_DEFINE_CONFIGURABLE (NAME, TYPE, DEFAULT, HELP ) \
75- Configurable<TYPE > NAME {# NAME , (DEFAULT ), (HELP )}; // NOLINT(bugprone-macro-parentheses)
74+ #define O2_DEFINE_CONFIGURABLE (name, type, defaultValue, help ) \
75+ Configurable<type> name{#name , (defaultValue ), (help )}; // NOLINT(bugprone-macro-parentheses)
7676
7777static constexpr float PairCutOff = -1 .f;
7878static constexpr std::array<std::array<float , 5 >, 1 > CfgPairCutDefaults{{{PairCutOff, PairCutOff, PairCutOff, PairCutOff, PairCutOff}}};
@@ -1787,6 +1787,8 @@ struct Lambdastarproxy {
17871787 // Inclusive PID-QA histograms are filled before final PID cuts, after event/track-quality cuts.
17881788 // Candidate-level nSigma/TOF/DCA histograms are filled after final PID cuts.
17891789 Configurable<int > lstarEnablePidQA{" lstarEnablePidQA" , 0 , " Enable PID QA histograms (dE/dx, TOF #beta, proxy invariant-mass QA, etc.): 1 = ON, 0 = OFF" };
1790+ Configurable<int > lstarEnableProxyControls{" lstarEnableProxyControls" , 1 , " Enable TOF/PID-partitioned proxy spectra and inclusive full-pK maps (requires lstarEnableSparse)" };
1791+ Configurable<int > lstarRequireTOFMatchDe{" lstarRequireTOFMatchDe" , 0 , " Require a TOF match for every selected deuteron; 0 preserves hybrid unmatched candidates" };
17901792 Configurable<int > lstarEnableSparse{" lstarEnableSparse" , 1 , " Enable THnSparse invariant-mass histograms (#Lambda^{*} pK and proxy); 1 = ON, 0 = OFF" };
17911793 Configurable<float > lstarLambdaAbsYMax{" lstarLambdaAbsYMax" , 0 .5f , " Max |y_{pK}| (or y_{proxy K}) for #Lambda^{*} candidates" };
17921794
@@ -1795,10 +1797,13 @@ struct Lambdastarproxy {
17951797 int charge;
17961798 int tid;
17971799 };
1800+ // PID flags describe detector compatibility, not truth-level purity.
17981801 struct ProxyCand {
17991802 float px, py, pz;
18001803 float pxFull, pyFull, pzFull;
18011804 bool protonLike;
1805+ bool hasTOF;
1806+ bool protonTPCCompatible;
18021807 int charge;
18031808 int tid;
18041809 };
@@ -2081,6 +2086,13 @@ struct Lambdastarproxy {
20812086 AxisSpec dcaXYAxis{200 , -0.2 , 0.2 , " DCA_{xy} (cm)" };
20822087 AxisSpec dcaZAxis{200 , -0.2 , 0.2 , " DCA_{z} (cm)" };
20832088
2089+ // Count reconstructed collisions received by the data process, before any
2090+ // task event cuts and after all of them, independently of track candidates.
2091+ histos.add (" hEventSelection" , " Proxy event selection;Selection stage;Events" ,
2092+ HistType::kTH1D , {AxisSpec{2 , 0.5 , 2.5 , " Selection stage" }});
2093+ histos.get <TH1 >(HIST (" hEventSelection" ))->GetXaxis ()->SetBinLabel (1 , " Before event selection" );
2094+ histos.get <TH1 >(HIST (" hEventSelection" ))->GetXaxis ()->SetBinLabel (2 , " After event selection" );
2095+
20842096 // Invariant-mass spectra
20852097 histos.add (" hInvMassPKUnlike" ,
20862098 " pK invariant mass (unlike-sign);M_{pK} (GeV/c^{2});Counts" ,
@@ -2092,6 +2104,30 @@ struct Lambdastarproxy {
20922104 // THnSparse for invariant-mass analysis (mass, pT, multiplicity/centrality)
20932105 if (lstarEnableSparse.value != 0 ) {
20942106
2107+ if (lstarEnableProxyControls.value != 0 ) {
2108+ // Axes 3/4/5 partition the SAME inclusive proxy sample in every pair class.
2109+ const std::vector<AxisSpec> controlAxes{
2110+ AxisSpec{400 , 1.4 , 1.8 , " M_{(d/2)K} (GeV/c^{2})" },
2111+ AxisSpec{100 , 0 ., 10 ., " p_{T}^{(d/2)K} (GeV/c)" }, centAxis,
2112+ AxisSpec{2 , -0.5 , 1.5 , " deuteron hasTOF (0/1)" },
2113+ AxisSpec{2 , -0.5 , 1.5 , " passes full proton PID (0/1)" },
2114+ AxisSpec{2 , -0.5 , 1.5 , " passes proton TPC cut only (0/1)" }};
2115+ histos.add (" hLambdaStarProxySelectedTrackControlSparse" , " Selected deuteron track controls" ,
2116+ HistType::kTHnSparseF ,
2117+ {AxisSpec{100 , 0 ., 10 ., " p_{T}^{d,full} (GeV/c)" }, controlAxes[3 ], controlAxes[4 ], controlAxes[5 ]}, true );
2118+ auto mapAxes = controlAxes;
2119+ // Full-pK rapidity is recorded, not imposed. Include mass flow bins
2120+ // when projecting these maps back onto the inclusive proxy sample.
2121+ mapAxes.emplace_back (1000 , 1.4 , 2.4 , " M_{pK}^{full} (GeV/c^{2})" );
2122+ mapAxes.emplace_back (2 , -0.5 , 1.5 , " passes full-pK rapidity (0/1)" );
2123+ for (auto const & pairClass : {" Unlike" , " Like" , " Mixed" }) {
2124+ const std::string spectrumName = std::string (" hLambdaStarProxyControl" ) + pairClass + " Sparse" ;
2125+ const std::string mapName = std::string (" hLambdaStarProxyControlFullPK" ) + pairClass + " Sparse" ;
2126+ histos.add (spectrumName.c_str (), " Inclusive proxy acceptance; PID compatibility controls" , HistType::kTHnSparseF , controlAxes, true );
2127+ histos.add (mapName.c_str (), " Inclusive proxy acceptance; full-pK control map" , HistType::kTHnSparseF , mapAxes, true );
2128+ }
2129+ }
2130+
20952131 histos.add (
20962132 " hLambdaStarProxyVsFullPKMixedSparse" ,
20972133 " d-selected mixed-event pairs: full-p proton hypothesis vs (d/2)K proxy;"
@@ -2587,6 +2623,7 @@ struct Lambdastarproxy {
25872623 bool passOptionalDeuteronTOFExtras (const TTrack& trk) const
25882624 {
25892625 const bool needTOF =
2626+ (lstarRequireTOFMatchDe.value != 0 ) ||
25902627 (lstarEnableBetaCutDe.value != 0 ) ||
25912628 (lstarEnableExpSignalTOFDe.value != 0 && lstarTOFExpSignalDiffDeMax.value > 0 .f );
25922629
@@ -2595,6 +2632,8 @@ struct Lambdastarproxy {
25952632 if (!trk.hasTOF ()) {
25962633 return false ;
25972634 }
2635+ } else {
2636+ return false ;
25982637 }
25992638 }
26002639
@@ -2758,12 +2797,20 @@ struct Lambdastarproxy {
27582797 std::array{m1, m2});
27592798 }
27602799
2761- void process (FilteredCollisions ::iterator const & collision, FilteredTracks const & tracks)
2800+ void process (CollisionsWithEvSel ::iterator const & collision, FilteredTracks const & tracks)
27622801 {
2802+ histos.fill (HIST (" hEventSelection" ), 1 .);
2803+ // Use unfiltered collisions here so the first bin includes vertex rejects.
2804+ // Preserve the strict vertex acceptance of collisionZVtxFilter; the MC QA
2805+ // process still uses that framework filter and does not fill this counter.
2806+ if (!(std::abs (collision.posZ ()) < lstarCutVertex.value )) {
2807+ return ;
2808+ }
27632809 // Event selection (cfgTrigger) -- AO2D only
27642810 if (!keepCollisionAO2D (collision)) {
27652811 return ;
27662812 }
2813+ histos.fill (HIST (" hEventSelection" ), 2 .);
27672814 // physics masses (GeV/c^2)
27682815 constexpr double MassProton = o2::constants::physics::MassProton;
27692816 constexpr double MassKaonCharged = o2::constants::physics::MassKaonCharged;
@@ -2901,7 +2948,8 @@ struct Lambdastarproxy {
29012948
29022949 const float nsTPCDe = trkD.tpcNSigmaDe ();
29032950 const float nsTOFDe = trkD.tofNSigmaDe ();
2904- const bool hasTofDe = hasTOFMatch (trkD);
2951+ // These controls require the actual match flag, never an inferred PID value.
2952+ const bool hasTofDe = trkD.hasTOF ();
29052953
29062954 if (!passOptionalDeuteronTOFExtras (trkD)) {
29072955 continue ;
@@ -3005,6 +3053,11 @@ struct Lambdastarproxy {
30053053 const float pzFull =
30063054 ptD * std::sinh (etaD);
30073055
3056+ if (lstarEnableSparse.value != 0 && lstarEnableProxyControls.value != 0 ) {
3057+ histos.fill (HIST (" hLambdaStarProxySelectedTrackControlSparse" ), ptD, hasTofDe,
3058+ passesProtonSelection, std::abs (nsTPCPrAsProxy) < lstarCutNsigmaTPCPr.value );
3059+ }
3060+
30083061 proxyCands.push_back (
30093062 ProxyCand{
30103063 .px = pxProxy,
@@ -3017,6 +3070,8 @@ struct Lambdastarproxy {
30173070
30183071 .protonLike =
30193072 passesProtonSelection,
3073+ .hasTOF = hasTofDe,
3074+ .protonTPCCompatible = std::abs (nsTPCPrAsProxy) < lstarCutNsigmaTPCPr.value ,
30203075
30213076 .charge =
30223077 static_cast <int >(
@@ -3274,6 +3329,16 @@ struct Lambdastarproxy {
32743329 // Inclusive invariant-mass spectrum for the #Lambda^{*} proxy (d/2 + K)
32753330 histos.fill (HIST (" hDeuteronProxyMass" ), mass);
32763331 if (lstarEnableSparse.value != 0 ) {
3332+ if (lstarEnableProxyControls.value != 0 ) {
3333+ const bool passFullY = std::abs (yFullPK) <= lstarLambdaAbsYMax.value ;
3334+ if (unlikeSignProxy) {
3335+ histos.fill (HIST (" hLambdaStarProxyControlUnlikeSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible );
3336+ histos.fill (HIST (" hLambdaStarProxyControlFullPKUnlikeSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible , massFullPK, passFullY);
3337+ } else {
3338+ histos.fill (HIST (" hLambdaStarProxyControlLikeSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible );
3339+ histos.fill (HIST (" hLambdaStarProxyControlFullPKLikeSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible , massFullPK, passFullY);
3340+ }
3341+ }
32773342
32783343 if (unlikeSignProxy) {
32793344
@@ -3536,6 +3601,12 @@ struct Lambdastarproxy {
35363601
35373602 if (lstarEnableSparse.value != 0 ) {
35383603
3604+ if (lstarEnableProxyControls.value != 0 ) {
3605+ const bool passFullY = std::abs (yFullPK) <= lstarLambdaAbsYMax.value ;
3606+ histos.fill (HIST (" hLambdaStarProxyControlMixedSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible );
3607+ histos.fill (HIST (" hLambdaStarProxyControlFullPKMixedSparse" ), mass, ptPair, eventMult, pr.hasTOF , pr.protonLike , pr.protonTPCCompatible , massFullPK, passFullY);
3608+ }
3609+
35393610 // Standard mixed-event proxy spectrum.
35403611 //
35413612 // This requires only the proxy hypothesis to satisfy
0 commit comments