3131#include " Framework/runDataProcessing.h"
3232#include " ReconstructionDataFormats/Track.h"
3333
34- #include < TLorentzVector.h>
3534#include < TMath.h>
3635#include < TObjArray.h>
3736#include < TPDGCode.h>
@@ -66,22 +65,22 @@ struct LfITSTPCMatchingSecondaryTracksQA {
6665 Configurable<double > zVtx{" zVtx" , 10.0 , " Maximum zVertex" };
6766
6867 // Track Parameters
69- Configurable<float > minITSnCls{" minITSnCls" , 1 .0f , " min number of ITS clusters" };
70- Configurable<float > minNCrossedRowsTPC{" minNCrossedRowsTPC" , 80 .0f , " min number of TPC crossed rows" };
68+ Configurable<float > minITSnCls{" minITSnCls" , 5 .0f , " min number of ITS clusters" };
69+ Configurable<float > minNCrossedRowsTPC{" minNCrossedRowsTPC" , 100 .0f , " min number of TPC crossed rows" };
7170 Configurable<float > maxChi2TPC{" maxChi2TPC" , 4 .0f , " max chi2 per cluster TPC" };
7271 Configurable<float > maxChi2ITS{" maxChi2ITS" , 36 .0f , " max chi2 per cluster ITS" };
7372 Configurable<float > etaMin{" etaMin" , -0 .8f , " eta min" };
7473 Configurable<float > etaMax{" etaMax" , +0 .8f , " eta max" };
7574 Configurable<float > nsigmaTPCmin{" nsigmaTPCmin" , -3 .0f , " Minimum nsigma TPC" };
7675 Configurable<float > nsigmaTPCmax{" nsigmaTPCmax" , +3 .0f , " Maximum nsigma TPC" };
7776 Configurable<float > nsigmaTOFmin{" nsigmaTOFmin" , -3 .0f , " Minimum nsigma TOF" };
78- Configurable<float > nsigmaTOFmax{" nsigmaTOFmax" , +3 .0f , " Maximum nsigma TOF" };
79- Configurable<float > dcaxyMax{" dcaxyMax" , 0 .1f , " dcaxy max" };
80- Configurable<float > dcazMax{" dcazMax" , 0 .1f , " dcaz max" };
77+ Configurable<float > nsigmaTOFmax{" nsigmaTOFmax" , +3 .5f , " Maximum nsigma TOF" };
78+ Configurable<float > dcaxyMax{" dcaxyMax" , 0 .05f , " dcaxy max" };
79+ Configurable<float > dcazMax{" dcazMax" , 0 .05f , " dcaz max" };
8180 Configurable<float > dcaMin{" dcaMin" , 0 .1f , " dca min" };
8281 Configurable<bool > requireTOF{" requireTOF" , false , " require TOF hit" };
8382 Configurable<bool > requireItsHits{" requireItsHits" , false , " require ITS hits" };
84- Configurable<std::vector<float >> requiredHit{" requiredHit" , {0 , 0 , 0 , 0 , 0 , 0 , 0 }, " required ITS Hits (1=required, 0=not required)" };
83+ Configurable<std::vector<float >> requiredHit{" requiredHit" , {1 , 1 , 1 , 0 , 0 , 0 , 0 }, " required ITS Hits (1=required, 0=not required)" };
8584
8685 // V0 Parameters
8786 Configurable<float > minimumV0Radius{" minimumV0Radius" , 0 .0f , " Minimum V0 Radius" };
@@ -106,6 +105,8 @@ struct LfITSTPCMatchingSecondaryTracksQA {
106105 registryData.add (" secPionTPC_ITS" , " secPionTPC_ITS" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
107106 registryData.add (" secPionV0TPC" , " secPionV0TPC" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
108107 registryData.add (" secPionV0TPC_ITS" , " secPionV0TPC_ITS" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
108+ registryData.add (" primProtonTPC" , " primProtonTPC" , HistType::kTH1D , {{500 , 0 , 5 , " #it{p}_{T} (GeV/#it{c})" }});
109+ registryData.add (" primProtonITS" , " primProtonITS" , HistType::kTH1D , {{500 , 0 , 5 , " #it{p}_{T} (GeV/#it{c})" }});
109110 }
110111
111112 if (doprocessMC) {
@@ -118,6 +119,8 @@ struct LfITSTPCMatchingSecondaryTracksQA {
118119 registryMC.add (" secPionTPC_ITS_MC" , " secPionTPC_ITS_MC" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
119120 registryMC.add (" secPionV0TPC_MC" , " secPionV0TPC_MC" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
120121 registryMC.add (" secPionV0TPC_ITS_MC" , " secPionV0TPC_ITS_MC" , HistType::kTH3D , {{100 , 0 , 10 , " #it{p}_{T} (GeV/#it{c})" }, {16 , -0.8 , 0.8 , " #eta" }, {100 , 0 , TwoPI, " #phi" }});
122+ registryMC.add (" primProtonTPC_MC" , " primProtonTPC_MC" , HistType::kTH1D , {{500 , 0 , 5 , " #it{p}_{T} (GeV/#it{c})" }});
123+ registryMC.add (" primProtonITS_MC" , " primProtonITS_MC" , HistType::kTH1D , {{500 , 0 , 5 , " #it{p}_{T} (GeV/#it{c})" }});
121124 }
122125 }
123126
@@ -210,6 +213,44 @@ struct LfITSTPCMatchingSecondaryTracksQA {
210213 return true ;
211214 }
212215
216+ template <typename protonTrack>
217+ bool passedProtonSelection (const protonTrack& track)
218+ {
219+ // Switch between TPC and TOF analysis
220+ static constexpr double PtThreshold = 0.6 ;
221+
222+ // TPC Selection
223+ if (track.pt () < PtThreshold && (track.tpcNSigmaPr () < nsigmaTPCmin || track.tpcNSigmaPr () > nsigmaTPCmax))
224+ return false ;
225+
226+ // TOF Selection
227+ if (track.pt () > PtThreshold && (track.tpcNSigmaPr () < nsigmaTPCmin || track.tpcNSigmaPr () > nsigmaTPCmax || track.tofNSigmaPr () < nsigmaTOFmin || track.tofNSigmaPr () > nsigmaTOFmax))
228+ return false ;
229+ return true ;
230+ }
231+
232+ template <typename ItsTrack>
233+ bool passedTrackSelectionItsPrimary (const ItsTrack& track)
234+ {
235+ if (!track.hasITS ())
236+ return false ;
237+ if (track.itsNCls () < minITSnCls)
238+ return false ;
239+ if (track.itsChi2NCl () > maxChi2ITS)
240+ return false ;
241+ static constexpr int NitsLayers = 7 ;
242+
243+ auto requiredItsHit = static_cast <std::vector<float >>(requiredHit);
244+ if (requireItsHits) {
245+ for (int i = 0 ; i < NitsLayers; i++) {
246+ if (requiredItsHit[i] > 0 && !hasHitOnITSlayer (track.itsClusterMap (), i)) {
247+ return false ;
248+ }
249+ }
250+ }
251+ return true ;
252+ }
253+
213254 template <typename ItsTrack>
214255 bool passedTrackSelectionIts (const ItsTrack& track)
215256 {
@@ -221,13 +262,14 @@ struct LfITSTPCMatchingSecondaryTracksQA {
221262 if (track.itsChi2NCl() > maxChi2ITS)
222263 return false;
223264 */
265+ static constexpr int NitsLayers = 7 ;
224266
225267 if (track.itsNCls () < minITSnCls)
226268 return false ;
227269
228270 auto requiredItsHit = static_cast <std::vector<float >>(requiredHit);
229271 if (requireItsHits) {
230- for (int i = 0 ; i < 7 ; i++) {
272+ for (int i = 0 ; i < NitsLayers ; i++) {
231273 if (requiredItsHit[i] > 0 && !hasHitOnITSlayer (track.itsClusterMap (), i)) {
232274 return false ;
233275 }
@@ -245,6 +287,27 @@ struct LfITSTPCMatchingSecondaryTracksQA {
245287 return ;
246288 registryData.fill (HIST (" number_of_events_data" ), 1.5 );
247289
290+ // Reject events near the ITS Read-Out Frame border
291+ if (!collision.selection_bit (o2::aod::evsel::kNoITSROFrameBorder ))
292+ return ;
293+ registryData.fill (HIST (" number_of_events_data" ), 2.5 );
294+
295+ // Reject events at the Time Frame border
296+ if (!collision.selection_bit (o2::aod::evsel::kNoTimeFrameBorder ))
297+ return ;
298+ registryData.fill (HIST (" number_of_events_data" ), 3.5 );
299+
300+ // Reject events with same-bunch pileup
301+ if (!collision.selection_bit (o2::aod::evsel::kNoSameBunchPileup ))
302+ return ;
303+ registryData.fill (HIST (" number_of_events_data" ), 4.5 );
304+
305+ // Require consistent FT0 vs PV z-vertex
306+ if (!collision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV ))
307+ return ;
308+ registryData.fill (HIST (" number_of_events_data" ), 5.5 );
309+
310+ // Loop over reconstructed tracks
248311 for (const auto & track : tracks) {
249312
250313 // DCA distributions
@@ -253,6 +316,12 @@ struct LfITSTPCMatchingSecondaryTracksQA {
253316 registryData.fill (HIST (" dcazDatavspt" ), track.pt (), track.dcaZ ());
254317 }
255318
319+ // Primary protons
320+ if (passedTrackSelectionTpcPrimary (track) && passedProtonSelection (track))
321+ registryData.fill (HIST (" primProtonTPC" ), track.pt ());
322+ if (passedTrackSelectionTpcPrimary (track) && passedProtonSelection (track) && passedTrackSelectionItsPrimary (track))
323+ registryData.fill (HIST (" primProtonITS" ), track.pt ());
324+
256325 // Primary Tracks
257326 if (passedTrackSelectionTpcPrimary (track) && passedPionSelection (track))
258327 registryData.fill (HIST (" primPionTPC" ), track.pt (), track.eta (), TVector2::Phi_0_2pi (track.phi ()));
@@ -293,9 +362,30 @@ struct LfITSTPCMatchingSecondaryTracksQA {
293362 for (const auto & collision : collisions) {
294363 registryMC.fill (HIST (" number_of_events_mc" ), 0.5 );
295364
365+ // Event Selection
296366 if (!collision.sel8 () || std::fabs (collision.posZ ()) > zVtx)
297367 continue ;
298- registryMC.fill (HIST (" number_of_events_mc" ), 1.5 );
368+ registryData.fill (HIST (" number_of_events_mc" ), 1.5 );
369+
370+ // Reject events near the ITS Read-Out Frame border
371+ if (!collision.selection_bit (o2::aod::evsel::kNoITSROFrameBorder ))
372+ continue ;
373+ registryData.fill (HIST (" number_of_events_mc" ), 2.5 );
374+
375+ // Reject events at the Time Frame border
376+ if (!collision.selection_bit (o2::aod::evsel::kNoTimeFrameBorder ))
377+ continue ;
378+ registryData.fill (HIST (" number_of_events_mc" ), 3.5 );
379+
380+ // Reject events with same-bunch pileup
381+ if (!collision.selection_bit (o2::aod::evsel::kNoSameBunchPileup ))
382+ continue ;
383+ registryData.fill (HIST (" number_of_events_mc" ), 4.5 );
384+
385+ // Require consistent FT0 vs PV z-vertex
386+ if (!collision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV ))
387+ continue ;
388+ registryData.fill (HIST (" number_of_events_mc" ), 5.5 );
299389
300390 auto v0sPerColl = fullV0s.sliceBy (perCollisionV0, collision.globalIndex ());
301391 auto tracksPerColl = mcTracks.sliceBy (perCollisionTrk, collision.globalIndex ());
@@ -308,6 +398,12 @@ struct LfITSTPCMatchingSecondaryTracksQA {
308398 registryMC.fill (HIST (" dcazMCvspt" ), track.pt (), track.dcaZ ());
309399 }
310400
401+ // Primary protons
402+ if (passedTrackSelectionTpcPrimary (track) && passedProtonSelection (track))
403+ registryMC.fill (HIST (" primProtonTPC_MC" ), track.pt ());
404+ if (passedTrackSelectionTpcPrimary (track) && passedProtonSelection (track) && passedTrackSelectionItsPrimary (track))
405+ registryMC.fill (HIST (" primProtonITS_MC" ), track.pt ());
406+
311407 // Primary Tracks
312408 if (passedTrackSelectionTpcPrimary (track) && passedPionSelection (track))
313409 registryMC.fill (HIST (" primPionTPC_MC" ), track.pt (), track.eta (), TVector2::Phi_0_2pi (track.phi ()));
0 commit comments