@@ -66,6 +66,7 @@ DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float);
6666DECLARE_SOA_COLUMN (NeutronClass, neutronClass, int );
6767DECLARE_SOA_COLUMN (IsGapTagged, isGapTagged, bool );
6868DECLARE_SOA_COLUMN (IsZDCTagged, isZDCTagged, bool );
69+ DECLARE_SOA_COLUMN (CollisionIndex, collisionIndex, int64_t );
6970} // namespace upcjetevent
7071
7172DECLARE_SOA_TABLE (UpcJetEvents, " AOD" , " UPCJETEVENT" ,
@@ -78,7 +79,8 @@ DECLARE_SOA_TABLE(UpcJetEvents, "AOD", "UPCJETEVENT",
7879 upcjetevent::TimeZNC,
7980 upcjetevent::NeutronClass,
8081 upcjetevent::IsGapTagged,
81- upcjetevent::IsZDCTagged);
82+ upcjetevent::IsZDCTagged,
83+ upcjetevent::CollisionIndex);
8284using UpcJetEvent = UpcJetEvents::iterator;
8385
8486namespace upcjet
@@ -106,13 +108,23 @@ DECLARE_SOA_INDEX_COLUMN_FULL(UpcJetEvent, upcJetEvent, int32_t, UpcJetEvents, "
106108DECLARE_SOA_COLUMN (Pt, pt, float );
107109DECLARE_SOA_COLUMN (Eta, eta, float );
108110DECLARE_SOA_COLUMN (Phi, phi, float );
111+ DECLARE_SOA_COLUMN (TrackCutFlag, trackCutFlag, uint16_t );
112+ DECLARE_SOA_COLUMN (TrackCutFlagFb5, trackCutFlagFb5, bool );
113+ DECLARE_SOA_COLUMN (DcaXY, dcaXY, float );
114+ DECLARE_SOA_COLUMN (DcaZ, dcaZ, float );
115+ DECLARE_SOA_COLUMN (PassesConfiguredSelection, passesConfiguredSelection, bool );
109116} // namespace upctrack
110117
111118DECLARE_SOA_TABLE (UpcTracks, " AOD" , " UPCTRACK" ,
112119 upctrack::UpcJetEventId,
113120 upctrack::Pt,
114121 upctrack::Eta,
115- upctrack::Phi);
122+ upctrack::Phi,
123+ upctrack::TrackCutFlag,
124+ upctrack::TrackCutFlagFb5,
125+ upctrack::DcaXY,
126+ upctrack::DcaZ,
127+ upctrack::PassesConfiguredSelection);
116128using UpcTrack = UpcTracks::iterator;
117129
118130namespace upcjettrack
@@ -147,6 +159,7 @@ DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float);
147159DECLARE_SOA_COLUMN (NeutronClass, neutronClass, int );
148160DECLARE_SOA_COLUMN (IsGapTagged, isGapTagged, bool );
149161DECLARE_SOA_COLUMN (IsZDCTagged, isZDCTagged, bool );
162+ DECLARE_SOA_COLUMN (CollisionIndex, collisionIndex, int64_t );
150163} // namespace upcjeteventmcd
151164
152165DECLARE_SOA_TABLE (UpcJetEventsMCD, " AOD" , " UPCJETEVENTMCD" ,
@@ -159,7 +172,8 @@ DECLARE_SOA_TABLE(UpcJetEventsMCD, "AOD", "UPCJETEVENTMCD",
159172 upcjeteventmcd::TimeZNC,
160173 upcjeteventmcd::NeutronClass,
161174 upcjeteventmcd::IsGapTagged,
162- upcjeteventmcd::IsZDCTagged);
175+ upcjeteventmcd::IsZDCTagged,
176+ upcjeteventmcd::CollisionIndex);
163177using UpcJetEventMCD = UpcJetEventsMCD::iterator;
164178
165179namespace upctrackmcd
@@ -168,13 +182,23 @@ DECLARE_SOA_INDEX_COLUMN_FULL(UpcJetEventMCD, upcJetEventMCD, int32_t, UpcJetEve
168182DECLARE_SOA_COLUMN (Pt, pt, float );
169183DECLARE_SOA_COLUMN (Eta, eta, float );
170184DECLARE_SOA_COLUMN (Phi, phi, float );
185+ DECLARE_SOA_COLUMN (TrackCutFlag, trackCutFlag, uint16_t );
186+ DECLARE_SOA_COLUMN (TrackCutFlagFb5, trackCutFlagFb5, bool );
187+ DECLARE_SOA_COLUMN (DcaXY, dcaXY, float );
188+ DECLARE_SOA_COLUMN (DcaZ, dcaZ, float );
189+ DECLARE_SOA_COLUMN (PassesConfiguredSelection, passesConfiguredSelection, bool );
171190} // namespace upctrackmcd
172191
173192DECLARE_SOA_TABLE (UpcTracksMCD, " AOD" , " UPCTRACKMCD" ,
174193 upctrackmcd::UpcJetEventMCDId,
175194 upctrackmcd::Pt,
176195 upctrackmcd::Eta,
177- upctrackmcd::Phi);
196+ upctrackmcd::Phi,
197+ upctrackmcd::TrackCutFlag,
198+ upctrackmcd::TrackCutFlagFb5,
199+ upctrackmcd::DcaXY,
200+ upctrackmcd::DcaZ,
201+ upctrackmcd::PassesConfiguredSelection);
178202using UpcTrackMCD = UpcTracksMCD::iterator;
179203
180204namespace upcjetmcd
@@ -332,8 +356,11 @@ struct JetUpcQa {
332356 Configurable<int > cfgMaxNTracks{" cfgMaxNTracks" , 100 , " Max tracks" };
333357
334358 Configurable<float > cfgTrackPtMin{" cfgTrackPtMin" , 0 .15f , " Min track pT (GeV/c)" };
359+ Configurable<float > cfgTrackPtMax{" cfgTrackPtMax" , 100 .f , " Max track pT (GeV/c), matching derived-data kinematics" };
335360 Configurable<float > cfgTrackEtaMax{" cfgTrackEtaMax" , 0 .9f , " Max track |eta|" };
336- Configurable<std::string> cfgTrackSelection{" cfgTrackSelection" , " kinematicsOnly" , " Reconstructed-track selection: kinematicsOnly, globalTracks, or udDefault" };
361+ Configurable<std::string> cfgTrackSelection{" cfgTrackSelection" , " derivedDataSelection" , " Reconstructed-track selection: derivedDataSelection, derivedQualityTracksWDCA, kinematicsOnly, globalTracks, or udDefault" };
362+ Configurable<float > cfgDerivedTrackDCAZMax{" cfgDerivedTrackDCAZMax" , 0 .2f , " Maximum |DCAz| for the derived-data QualityTracksWDCA selection (cm)" };
363+ Configurable<float > cfgVertexZCut{" cfgVertexZCut" , 10 .f , " Maximum absolute collision vertex z (cm)" };
337364 Configurable<float > cfgTrackDCAZMax{" cfgTrackDCAZMax" , 2 .f , " Maximum |DCAz| for udDefault track selection (cm)" };
338365 Configurable<float > cfgTrackDCAXYMax{" cfgTrackDCAXYMax" , 0 .f , " Maximum |DCAxy| for udDefault (cm); 0 uses the pT-dependent UD cut" };
339366 Configurable<float > cfgTrackTPCChi2NClMax{" cfgTrackTPCChi2NClMax" , 4 .f , " Maximum TPC chi2 per cluster for udDefault" };
@@ -367,23 +394,29 @@ struct JetUpcQa {
367394
368395 HistogramRegistry registry{" registry" };
369396 enum class TrackSelectionMode {
397+ DerivedDataSelection,
398+ DerivedQualityTracksWDCA,
370399 KinematicsOnly,
371400 GlobalTracks,
372401 UDDefault
373402 };
374- TrackSelectionMode trackSelectionMode = TrackSelectionMode::KinematicsOnly ;
403+ TrackSelectionMode trackSelectionMode = TrackSelectionMode::DerivedDataSelection ;
375404
376405 // Init
377406 void init (InitContext&)
378407 {
379- if (cfgTrackSelection.value == " kinematicsOnly" ) {
408+ if (cfgTrackSelection.value == " derivedDataSelection" ) {
409+ trackSelectionMode = TrackSelectionMode::DerivedDataSelection;
410+ } else if (cfgTrackSelection.value == " derivedQualityTracksWDCA" ) {
411+ trackSelectionMode = TrackSelectionMode::DerivedQualityTracksWDCA;
412+ } else if (cfgTrackSelection.value == " kinematicsOnly" ) {
380413 trackSelectionMode = TrackSelectionMode::KinematicsOnly;
381414 } else if (cfgTrackSelection.value == " globalTracks" ) {
382415 trackSelectionMode = TrackSelectionMode::GlobalTracks;
383416 } else if (cfgTrackSelection.value == " udDefault" ) {
384417 trackSelectionMode = TrackSelectionMode::UDDefault;
385418 } else {
386- LOGP (fatal, " Unknown cfgTrackSelection '{}'. Choose kinematicsOnly, globalTracks, or udDefault." , cfgTrackSelection.value );
419+ LOGP (fatal, " Unknown cfgTrackSelection '{}'. Choose derivedDataSelection, derivedQualityTracksWDCA, kinematicsOnly, globalTracks, or udDefault." , cfgTrackSelection.value );
387420 }
388421
389422 sgCuts.SetNDtcoll (cfgNDtcoll);
@@ -420,12 +453,29 @@ struct JetUpcQa {
420453 registry.add (" hSelectionBitsMCD" , " Selection bits (MCD);0 all 1 gap 2 zdc 3 accepted;Counts" , {HistType::kTH1F , {{4 , -0.5 , 3.5 }}});
421454 }
422455
456+ template <typename TTrack>
457+ bool passesTrackKinematics (TTrack const & track) const
458+ {
459+ return std::abs (track.eta ()) <= cfgTrackEtaMax.value &&
460+ track.pt () >= cfgTrackPtMin.value &&
461+ track.pt () <= cfgTrackPtMax.value ;
462+ }
463+
423464 template <typename TTrack>
424465 bool isSelectedTrack (TTrack const & track) const
425466 {
426- if (std::abs (track. eta ()) > cfgTrackEtaMax. value || track. pt () < cfgTrackPtMin. value ) {
467+ if (! passesTrackKinematics (track) ) {
427468 return false ;
428469 }
470+ if (trackSelectionMode == TrackSelectionMode::DerivedQualityTracksWDCA) {
471+ // Mirror JetDerivedDataUtilities::setTrackSelectionBit(...): QualityTracksWDCA.
472+ return track.isQualityTrack () && std::abs (track.dcaZ ()) < cfgDerivedTrackDCAZMax.value ;
473+ }
474+ if (trackSelectionMode == TrackSelectionMode::DerivedDataSelection) {
475+ // Match the derived-data writer: retain tracks passing any stored selection bit
476+ // (global, quality, or hybrid). QualityTracksWDCA is a subset of QualityTracks.
477+ return track.isGlobalTrackWoPtEta () || track.isQualityTrack () || track.trackCutFlagFb5 ();
478+ }
429479 if (trackSelectionMode == TrackSelectionMode::KinematicsOnly) {
430480 return true ;
431481 }
@@ -505,9 +555,10 @@ struct JetUpcQa {
505555 return zdc.neutronClass > 0 ;
506556 }
507557
508- bool isAcceptedEvent (bool isGapTagged, bool isZDCTagged) const
558+ bool isAcceptedEvent (bool isGapTagged, bool isZDCTagged, float posZ ) const
509559 {
510- return (!cfgUseGapTagging.value || isGapTagged) &&
560+ return std::abs (posZ) <= cfgVertexZCut.value &&
561+ (!cfgUseGapTagging.value || isGapTagged) &&
511562 (!cfgUseZDCTagging.value || isZDCTagged);
512563 }
513564
@@ -748,7 +799,7 @@ struct JetUpcQa {
748799 int gapSide = gapInfo.gapSide ;
749800 bool isGapTagged = isSelectedGap (gapSide);
750801 bool isZDCTagged = isSelectedZDC (gapInfo.zdc );
751- bool isAccepted = isAcceptedEvent (isGapTagged, isZDCTagged);
802+ bool isAccepted = isAcceptedEvent (isGapTagged, isZDCTagged, collision. posZ () );
752803 registry.fill (HIST (" hGapSide" ), gapSide);
753804 registry.fill (HIST (" hZNAEnergy" ), gapInfo.zdc .energyCommonZNA );
754805 registry.fill (HIST (" hZNCEnergy" ), gapInfo.zdc .energyCommonZNC );
@@ -773,7 +824,9 @@ struct JetUpcQa {
773824 gapInfo.zdc .timeZNC ,
774825 gapInfo.zdc .neutronClass ,
775826 isGapTagged,
776- isZDCTagged);
827+ isZDCTagged,
828+ collision.globalIndex ());
829+ // This is the row index in our output event table, not the input collision index.
777830 int evtIdx = upcJetEventTable.lastIndex ();
778831
779832 std::vector<fastjet::PseudoJet> fjInput;
@@ -783,12 +836,17 @@ struct JetUpcQa {
783836 if (t.collisionId () != collision.globalIndex ()) {
784837 continue ;
785838 }
786- if (!isSelectedTrack (t)) {
839+ if (!passesTrackKinematics (t)) {
787840 continue ;
788841 }
842+ bool passesConfiguredSelection = isSelectedTrack (t);
789843
790- // event-level track table
791- upcTrackTable (evtIdx, t.pt (), t.eta (), t.phi ());
844+ // Store all kinematically accepted candidates and the current decision so
845+ // alternate track selections can be reproduced from the output table.
846+ upcTrackTable (evtIdx, t.pt (), t.eta (), t.phi (), t.trackCutFlag (), t.trackCutFlagFb5 (), t.dcaXY (), t.dcaZ (), passesConfiguredSelection);
847+ if (!passesConfiguredSelection) {
848+ continue ;
849+ }
792850
793851 // jet finding input
794852 fastjet::PseudoJet p;
@@ -843,7 +901,7 @@ struct JetUpcQa {
843901 int gapSide = gapInfo.gapSide ;
844902 bool isGapTagged = isSelectedGap (gapSide);
845903 bool isZDCTagged = isSelectedZDC (gapInfo.zdc );
846- bool isAccepted = isAcceptedEvent (isGapTagged, isZDCTagged);
904+ bool isAccepted = isAcceptedEvent (isGapTagged, isZDCTagged, collision. posZ () );
847905 registry.fill (HIST (" hGapSideMCD" ), gapSide);
848906 registry.fill (HIST (" hZNAEnergyMCD" ), gapInfo.zdc .energyCommonZNA );
849907 registry.fill (HIST (" hZNCEnergyMCD" ), gapInfo.zdc .energyCommonZNC );
@@ -868,7 +926,8 @@ struct JetUpcQa {
868926 gapInfo.zdc .timeZNC ,
869927 gapInfo.zdc .neutronClass ,
870928 isGapTagged,
871- isZDCTagged);
929+ isZDCTagged,
930+ collision.globalIndex ());
872931 int evtIdx = upcJetEventTableMCD.lastIndex ();
873932
874933 std::vector<fastjet::PseudoJet> fjInput;
@@ -878,11 +937,15 @@ struct JetUpcQa {
878937 if (t.collisionId () != collision.globalIndex ()) {
879938 continue ;
880939 }
881- if (!isSelectedTrack (t)) {
940+ if (!passesTrackKinematics (t)) {
882941 continue ;
883942 }
943+ bool passesConfiguredSelection = isSelectedTrack (t);
884944
885- upcTrackTableMCD (evtIdx, t.pt (), t.eta (), t.phi ());
945+ upcTrackTableMCD (evtIdx, t.pt (), t.eta (), t.phi (), t.trackCutFlag (), t.trackCutFlagFb5 (), t.dcaXY (), t.dcaZ (), passesConfiguredSelection);
946+ if (!passesConfiguredSelection) {
947+ continue ;
948+ }
886949
887950 fastjet::PseudoJet p;
888951 p.reset_PtYPhiM (t.pt (), t.eta (), t.phi (), o2::constants::physics::MassPiPlus);
0 commit comments