1414// / \author Francesca Ercolessi francesca.ercolessi@cern.ch
1515// / \since Dec 17, 2025
1616
17- // #include "../filterTables.h"
18-
19- #include " PWGLF/DataModel/LFParticleIdentification.h"
17+ #include " ../filterTables.h"
2018
2119#include " Common/Core/RecoDecay.h"
2220#include " Common/Core/TrackSelection.h"
2321#include " Common/Core/trackUtilities.h"
24- #include " Common/DataModel/Centrality.h"
2522#include " Common/DataModel/CollisionAssociationTables.h"
2623#include " Common/DataModel/EventSelection.h"
27- #include " Common/DataModel/Multiplicity .h"
24+ #include " Common/DataModel/PIDResponseITS .h"
2825#include " Common/DataModel/PIDResponseTOF.h"
26+ #include " Common/DataModel/PIDResponseTPC.h"
2927#include " Common/DataModel/TrackSelectionTables.h"
3028
3129#include " CCDB/BasicCCDBManager.h"
3230#include " CommonConstants/PhysicsConstants.h"
33- #include " DCAFitter/DCAFitterN.h"
3431#include " DataFormatsParameters/GRPMagField.h"
3532#include " DataFormatsParameters/GRPObject.h"
3633#include " DetectorsBase/Propagator.h"
4845struct H2fromLbFilter {
4946
5047 // Recall the output table
51- // Produces<aod::H2fromLbFilters> table;
48+ o2::framework:: Produces<o2:: aod::H2fromLbFilters> table;
5249
5350 o2::framework::Configurable<int > nBinsPt{" nBinsPt" , 100 , " N bins in pT histo" };
5451
@@ -69,23 +66,27 @@ struct H2fromLbFilter {
6966 o2::framework::Configurable<bool > isNoITSROFrameBorder{" isNoITSROFrameBorder" , true , " isNoITSROFrameBorder event selection" };
7067 o2::framework::Configurable<float > cfgTPCNsigma{" cfgTPCNsigma" , 4 .0f , " TPC n sigma for deuteron PID" };
7168 o2::framework::Configurable<float > cfgTOFNsigma{" cfgTOFNsigma" , 4 .0f , " TOF n sigma for deuteron PID" };
69+ o2::framework::Configurable<float > cfgITSNsigma{" cfgITSNsigma" , -2 .0f , " ITS n sigma for deuteron PID" };
7270 o2::framework::Configurable<float > cfgEta{" cfgEta" , 0 .8f , " Track eta selection" };
7371 o2::framework::Configurable<int > cfgTPCNclsFound{" cfgTPCNclsFound" , 100 , " Minimum TPC clusters found" };
7472 o2::framework::Configurable<float > cfgTPCChi2Ncl{" cfgTPCChi2Ncl" , 4 .0f , " Maximum TPC chi2 per N clusters" };
7573 o2::framework::Configurable<float > cfgITSChi2Ncl{" cfgITSChi2Ncl" , 36 .0f , " Maximum ITS chi2 per N clusters" };
7674 o2::framework::Configurable<int > cfgITScls{" cfgITScls" , 2 , " Minimum ITS clusters" };
7775 o2::framework::Configurable<float > cfgMaxPt{" cfgMaxPt" , 5 .0f , " Maximum pT cut" };
78- o2::framework::Configurable<float > cfgMinPt{" cfgMinPt" , 1 . 0f , " Maximum pT cut" };
76+ o2::framework::Configurable<float > cfgMinPt{" cfgMinPt" , 0 . 5f , " Minimum pT cut" };
7977 o2::framework::Configurable<float > cfgDCAcut{" cfgDCAcut" , 0 .003f , " DCA cut for non prompt deuteron" };
80- using myCompleteTracks = o2::soa::Join<o2::aod::Tracks, o2::aod::TracksExtra, o2::aod::TracksDCA, o2::aod::McTrackLabels>;
78+ o2::framework::Configurable<float > ptThresholdPid{" ptThresholdPid" , 1 .0f , " pT threshold to switch between ITS and TOF PID" };
79+
8180 o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
81+ o2::framework::Service<o2::pid::tof::TOFResponse> tofResponse;
8282
83- void init (o2::framework::InitContext&)
83+ void init (o2::framework::InitContext& initContext )
8484 {
85- ccdb->setURL (" http://alice-ccdb.cern.ch" );
85+ ccdb->setURL (" http://alice-ccdb.cern.ch" ); // Set CCDB URL to get magnetic field
8686 ccdb->setCaching (true );
8787 ccdb->setLocalObjectValidityChecking ();
8888 ccdb->setCreatedNotAfter (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ());
89+ tofResponse->initSetup (ccdb, initContext);
8990
9091 o2::framework::AxisSpec ptAxis = {100 , 0 .0f , 10 .0f , " #it{p}_{T} (GeV/#it{c})" };
9192
@@ -95,6 +96,7 @@ struct H2fromLbFilter {
9596 QAHistos.add (" hDCAzVsPt" , " DCAz #bar{d} vs p_{T}" , {o2::framework::HistType::kTH2D , {pTAxis, DCAzAxis}});
9697 QAHistos.add (" hnSigmaTPCVsPt" , " n#sigma TPC vs p_{T} for #bar{d} hypothesis; p_{T} (GeV/c); n#sigma TPC" , {o2::framework::HistType::kTH2D , {pTAxis, nSigmaAxis}});
9798 QAHistos.add (" hnSigmaTOFVsPt" , " n#sigma TOF vs p_{T} for #bar{d} hypothesis; p_{T} (GeV/c); n#sigma TOF" , {o2::framework::HistType::kTH2D , {pTAxis, nSigmaAxis}});
99+ QAHistos.add (" hnSigmaITSVsPt" , " n#sigma ITS vs p_{T} for #bar{d} hypothesis; p_{T} (GeV/c); n#sigma ITS" , {o2::framework::HistType::kTH2D , {pTAxis, nSigmaAxis}});
98100 QAHistos.add (" ptAntiDeuteron" , " ptAntiDeuteron" , {o2::framework::HistType::kTH1F , {ptAxis}});
99101 QAHistos.add (" etaAntideuteron" , " etaAntideuteron" , {o2::framework::HistType::kTH1F , {{100 , -1 .0f , 1 .0f , " eta #bar{d}" }}});
100102 QAHistos.add (" hDCAxyVsPt-pre_selection" , " DCAxy #bar{d} vs p_{T}" , {o2::framework::HistType::kTH2D , {pTAxis, DCAxyAxis}});
@@ -106,12 +108,15 @@ struct H2fromLbFilter {
106108 hProcessedEvents->GetXaxis ()->SetBinLabel (3 , " TF border" );
107109 hProcessedEvents->GetXaxis ()->SetBinLabel (4 , " ITS-RO border" );
108110 hProcessedEvents->GetXaxis ()->SetBinLabel (5 , " z-vertex" );
109- hProcessedEvents->GetXaxis ()->SetBinLabel (6 , " Trigger " );
111+ hProcessedEvents->GetXaxis ()->SetBinLabel (6 , o2::aod::filtering::H2fromLb::columnLabel () );
110112 }
111113
112114 // Tables
113115 using CollisionCandidates = o2::soa::Join<o2::aod::Collisions, o2::aod::EvSels>;
114- using TrackCandidates = o2::soa::Join<o2::aod::Tracks, o2::aod::TracksCov, o2::aod::TracksExtra, o2::aod::TracksDCA, o2::aod::TrackSelection, o2::aod::pidTPCFullDe, o2::aod::pidTOFFullDe>;
116+ using TrackCandidates = o2::soa::Join<o2::aod::Tracks, o2::aod::TracksCov, o2::aod::TracksExtra,
117+ o2::aod::TracksDCA, o2::aod::TrackSelection,
118+ o2::aod::pidTPCFullDe, o2::aod::pidTOFFullDe,
119+ o2::aod::TOFSignal, o2::aod::TOFEvTime>;
115120
116121 // Single-Track Selection
117122 template <typename T1>
@@ -144,21 +149,22 @@ struct H2fromLbFilter {
144149 return true ;
145150 }
146151
147- /* void fillTriggerTable(bool keepEvent[])
152+ void fillTriggerTable (bool keepEvent[])
148153 {
149154 table (keepEvent[0 ]);
150- }*/
155+ }
151156
152157 o2::framework::Preslice<o2::aod::TrackAssoc> trackIndicesPerCollision = o2::aod::track_association::collisionId;
153158 int mCurrentRun = -1 ;
159+
154160 void process (CollisionCandidates const & collisions,
155161 o2::aod::TrackAssoc const & trackIndices,
156162 TrackCandidates const & tracks,
157- o2::aod::BCsWithTimestamps const &)
163+ o2::aod::BCsWithTimestamps const & bcs )
158164 {
159- for (const auto & collision : collisions) // start loop over collisions
165+ tofResponse->processSetup (bcs.iteratorAt (0 )); // Update the response parameters
166+ for (const auto & collision : collisions) // start loop over collisions
160167 {
161- LOG (debug) << " Processing collision with ID: " << collision.globalIndex ();
162168 if (mCurrentRun != collision.bc_as <o2::aod::BCsWithTimestamps>().runNumber ()) { // If the run is new then we need to initialize the propagator field
163169 o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp <o2::parameters::GRPMagField>(" GLO/Config/GRPMagField" , collision.bc_as <o2::aod::BCsWithTimestamps>().timestamp ());
164170 o2::base::Propagator::initFieldFromGRP (grpo);
@@ -170,35 +176,50 @@ struct H2fromLbFilter {
170176 hProcessedEvents->Fill (0.5 );
171177 // Event selection cuts
172178 if (isTVX && !collision.selection_bit (o2::aod::evsel::kIsTriggerTVX )) {
173- // fillTriggerTable(keepEvent);
179+ fillTriggerTable (keepEvent);
174180 continue ;
175181 }
176182 hProcessedEvents->Fill (1.5 );
177183 if (isNoTimeFrameBorder && !collision.selection_bit (o2::aod::evsel::kNoTimeFrameBorder )) {
178- // fillTriggerTable(keepEvent);
184+ fillTriggerTable (keepEvent);
179185 continue ;
180186 }
181187 hProcessedEvents->Fill (2.5 );
182188 if (isNoITSROFrameBorder && !collision.selection_bit (o2::aod::evsel::kNoITSROFrameBorder )) {
183- // fillTriggerTable(keepEvent);
189+ fillTriggerTable (keepEvent);
184190 continue ;
185191 }
186192 hProcessedEvents->Fill (3.5 );
187193 if (std::abs (collision.posZ ()) > cutzvertex) {
188- // fillTriggerTable(keepEvent);
194+ fillTriggerTable (keepEvent);
189195 continue ;
190196 }
191- LOG (debug) << " Accepted collision!" ;
192197 hProcessedEvents->Fill (4.5 );
193198 QAHistos.fill (HIST (" hVtxZ" ), collision.posZ ());
194199
195200 // Loop over tracks
196- LOG (debug) << " Trying the slice" ;
197201 const auto & trackIdsThisCollision = trackIndices.sliceBy (trackIndicesPerCollision, collision.globalIndex ());
198- LOG (debug) << " Sliced!" ;
202+ auto tracksWithItsPid = o2::soa::Attach<TrackCandidates, o2::aod::pidits::ITSNSigmaDe>(tracks);
203+
204+ float tofEventTime = 0 .f ;
205+ float tofEventTimeErr = 0 .f ;
206+
207+ for (const auto & trackId : trackIdsThisCollision) { // start loop over tracks
208+ const auto & track = tracksWithItsPid.rawIteratorAt (trackId.trackId ());
209+ if (!passedSingleTrackSelection (track)) {
210+ continue ;
211+ }
212+ if (track.collisionId () != collision.globalIndex ()) {
213+ continue ;
214+ }
215+ tofEventTime = track.tofEvTime ();
216+ tofEventTimeErr = track.tofEvTimeErr ();
217+ break ;
218+ }
219+
199220 for (const auto & trackId : trackIdsThisCollision) { // start loop over tracks
200- LOG (debug) << " Processing track with ID: " << trackId. trackId ();
201- const auto & track = tracks .rawIteratorAt (trackId.trackId ());
221+
222+ const auto & track = tracksWithItsPid .rawIteratorAt (trackId.trackId ());
202223
203224 std::array<float , 2 > dca{track.dcaXY (), track.dcaZ ()};
204225 std::array<float , 3 > pVec = track.pVector ();
@@ -212,36 +233,61 @@ struct H2fromLbFilter {
212233 if (!passedSingleTrackSelection (track)) {
213234 continue ;
214235 }
215-
236+ float recalculatedNSigmaTOFDe = 0 .f ;
237+ if (track.collisionId () != collision.globalIndex ()) {
238+ recalculatedNSigmaTOFDe = tofResponse->nSigma <o2::track::PID::Deuteron>(track.tofSignalInAnotherBC (track.collision_as <CollisionCandidates>().bc_as <o2::aod::BCsWithTimestamps>().globalBC (), collision.bc_as <o2::aod::BCsWithTimestamps>().globalBC ()),
239+ track.tofExpMom (), track.length (), track.p (), track.eta (), tofEventTime, tofEventTimeErr);
240+ }
216241 const bool isTOFDe = std::abs (track.tofNSigmaDe ()) < cfgTOFNsigma;
217242 const bool isTPCDe = std::abs (track.tpcNSigmaDe ()) < cfgTPCNsigma;
218-
219- if (isTPCDe && isTOFDe) {
220-
221- QAHistos.fill (HIST (" hDCAxyVsPt-pre_selection" ), track.pt (), dca[0 ]);
222- QAHistos.fill (HIST (" hDCAzVsPt-pre-selection" ), track.pt (), dca[1 ]);
223- if (std::abs (dca[0 ]) < cfgDCAcut) {
224- continue ;
243+ const bool isITSDe = track.itsNSigmaDe () > cfgITSNsigma;
244+
245+ if (track.pt () < ptThresholdPid) {
246+ if (isTPCDe && isITSDe) {
247+ QAHistos.fill (HIST (" hDCAxyVsPt-pre_selection" ), track.pt (), dca[0 ]);
248+ QAHistos.fill (HIST (" hDCAzVsPt-pre-selection" ), track.pt (), dca[1 ]);
249+ if (std::abs (dca[0 ]) < cfgDCAcut) {
250+ continue ;
251+ }
252+ keepEvent[0 ] = true ;
253+ QAHistos.fill (HIST (" ptAntiDeuteron" ), track.pt ());
254+ QAHistos.fill (HIST (" etaAntideuteron" ), track.eta ());
255+ QAHistos.fill (HIST (" hDCAxyVsPt" ), track.pt (), dca[0 ]);
256+ QAHistos.fill (HIST (" hDCAzVsPt" ), track.pt (), dca[1 ]);
257+ QAHistos.fill (HIST (" hnSigmaTPCVsPt" ), track.pt (), track.tpcNSigmaDe ());
258+ QAHistos.fill (HIST (" hnSigmaTOFVsPt" ), track.pt (), track.tofNSigmaDe ());
259+ QAHistos.fill (HIST (" hnSigmaITSVsPt" ), track.pt (), track.itsNSigmaDe ());
260+ }
261+ } else {
262+ if (isTPCDe && isTOFDe) {
263+
264+ QAHistos.fill (HIST (" hDCAxyVsPt-pre_selection" ), track.pt (), dca[0 ]);
265+ QAHistos.fill (HIST (" hDCAzVsPt-pre-selection" ), track.pt (), dca[1 ]);
266+ if (std::abs (dca[0 ]) < cfgDCAcut) {
267+ continue ;
268+ }
269+ keepEvent[0 ] = true ;
270+ QAHistos.fill (HIST (" ptAntiDeuteron" ), track.pt ());
271+ QAHistos.fill (HIST (" etaAntideuteron" ), track.eta ());
272+ QAHistos.fill (HIST (" hDCAxyVsPt" ), track.pt (), dca[0 ]);
273+ QAHistos.fill (HIST (" hDCAzVsPt" ), track.pt (), dca[1 ]);
274+ QAHistos.fill (HIST (" hnSigmaTPCVsPt" ), track.pt (), track.tpcNSigmaDe ());
275+ QAHistos.fill (HIST (" hnSigmaTOFVsPt" ), track.pt (), track.tofNSigmaDe ());
276+ QAHistos.fill (HIST (" hnSigmaITSVsPt" ), track.pt (), track.itsNSigmaDe ());
225277 }
226- keepEvent[0 ] = true ;
227- QAHistos.fill (HIST (" ptAntiDeuteron" ), track.pt ());
228- QAHistos.fill (HIST (" etaAntideuteron" ), track.eta ());
229- QAHistos.fill (HIST (" hDCAxyVsPt" ), track.pt (), dca[0 ]);
230- QAHistos.fill (HIST (" hDCAzVsPt" ), track.pt (), dca[1 ]);
231- QAHistos.fill (HIST (" hnSigmaTPCVsPt" ), track.pt (), track.tpcNSigmaDe ());
232- QAHistos.fill (HIST (" hnSigmaTOFVsPt" ), track.pt (), track.tofNSigmaDe ());
233278 }
234-
235279 } // end track loop
236280 if (keepEvent[0 ]) {
237281 hProcessedEvents->Fill (5.5 );
238282 }
239- // fillTriggerTable(keepEvent);
283+
284+ fillTriggerTable (keepEvent);
240285 }
241286 }
242287};
243288
244289o2::framework::WorkflowSpec defineDataProcessing (o2::framework::ConfigContext const & cfgc)
245290{
291+ o2::pid::tof::TOFResponseImpl::metadataInfo.initMetadata (cfgc);
246292 return o2::framework::WorkflowSpec{o2::framework::adaptAnalysisTask<H2fromLbFilter>(cfgc)};
247293}
0 commit comments