1010// or submit itself to any jurisdiction.
1111
1212// task for charged particle pt spectra vs multiplicity analysis with 2d unfolding for run3+
13- // mimics https://github.com/alisw/AliPhysics/blob/master/PWGLF/SPECTRA/ChargedHadrons/MultDepSpec/AliMultDepSpecAnalysisTask.cxx
13+ // mimics Run1&2 version https://github.com/alisw/AliPhysics/blob/master/PWGLF/SPECTRA/ChargedHadrons/MultDepSpec/AliMultDepSpecAnalysisTask.cxx
14+ // and is compatible with postprocessing https://gitlab.cern.ch/mkruger/unfoldingframework
1415
1516#include " Framework/HistogramRegistry.h"
1617#include " ReconstructionDataFormats/Track.h"
2021#include " Common/DataModel/EventSelection.h"
2122#include " Common/DataModel/Centrality.h"
2223#include " Common/DataModel/TrackSelectionTables.h"
24+ #include " Common/Core/TrackSelection.h"
25+ #include " Common/Core/TrackSelectionDefaults.h"
2326#include " TDatabasePDG.h"
2427
2528using namespace o2 ;
2629using namespace o2 ::framework;
30+ using aod::track::TrackSelectionFlags;
2731
2832// --------------------------------------------------------------------------------------------------
2933// --------------------------------------------------------------------------------------------------
@@ -35,16 +39,20 @@ struct chargedSpectra {
3539 HistogramRegistry histos;
3640 Service<o2::framework::O2DatabasePDG> pdg;
3741
38- // task settings that can be steered via hyperloop
3942 Configurable<bool > isRun3{" isRun3" , true , " is Run3 dataset" };
4043 Configurable<uint32_t > maxMultMeas{" maxMultMeas" , 100 , " max measured multiplicity" };
4144 Configurable<uint32_t > maxMultTrue{" maxMultTrue" , 100 , " max true multiplicity" };
4245 Configurable<float > etaCut{" etaCut" , 0 .8f , " eta cut" };
4346 Configurable<float > ptMinCut{" ptMinCut" , 0 .15f , " pt min cut" };
4447 Configurable<float > ptMaxCut{" ptMaxCut" , 10 .f , " pt max cut" };
45-
4648 Configurable<bool > normINELGT0{" normINELGT0" , false , " normalize INEL>0 according to MC" };
4749
50+ Configurable<uint32_t > cutMode{" cutMode" , 100 , " track cut variation for systematics" };
51+ uint16_t trackSelMask{TrackSelectionFlags::kGlobalTrackWoPtEta }; // track selection bitmask (without cut that is being varied)
52+ uint16_t cutVarFlag{0 };
53+ TrackSelection trackSel;
54+ TrackSelection::TrackCuts trackSelFlag;
55+
4856 // helper struct to store transient properties
4957 struct varContainer {
5058 uint32_t multMeas{0u };
@@ -77,31 +85,17 @@ struct chargedSpectra {
7785 void processTrue (const C& collision, const P& particles);
7886
7987 using CollisionTableData = soa::Join<aod::Collisions, aod::EvSels>;
80- using TrackTableData = soa::Join<aod::Tracks , aod::TrackSelection>;
88+ using TrackTableData = soa::Join<aod::FullTracks, aod::TracksDCA , aod::TrackSelection>;
8189 void processData (CollisionTableData::iterator const & collision, TrackTableData const & tracks);
8290 PROCESS_SWITCH (chargedSpectra, processData, " process data" , false );
8391
8492 using CollisionTableMCTrue = aod::McCollisions;
8593 using CollisionTableMC = soa::SmallGroups<soa::Join<aod::McCollisionLabels, aod::Collisions, aod::EvSels>>;
86- using TrackTableMC = soa::Join<aod::Tracks , aod::McTrackLabels , aod::TrackSelection>;
94+ using TrackTableMC = soa::Join<aod::FullTracks , aod::TracksDCA , aod::TrackSelection, aod::McTrackLabels >;
8795 using ParticleTableMC = aod::McParticles;
8896 Preslice<TrackTableMC> perCollision = aod::track::collisionId;
8997 void processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks, ParticleTableMC const & particles);
9098 PROCESS_SWITCH (chargedSpectra, processMC, " process mc" , true );
91-
92- // TODO: - Milestone - express most of the selections on events and tracks in a declarative way to improve performance
93- /*
94- add
95- Filter xy;
96- soa::Filtered<Table>
97-
98- For the collision and track tables (data and MC):
99- - collision z pos < 10cm
100- - trigger condition + event selection
101- - track selection + is in kine range
102-
103- For the MC tables we need to keep everything that EITHER fulfils the conditions in data OR in MC to get correct efficiencies and contamination!
104- */
10599};
106100
107101WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
@@ -162,6 +156,62 @@ void chargedSpectra::init(InitContext const&)
162156 histos.add (" multPtSpec_trk_meas_evtcont" , " " , kTH2D , {multMeasAxis, ptMeasAxis}); // tracks from events that are measured, but do not belong to the desired class of events
163157 histos.add (" multPtSpec_trk_inter" , " " , kTH2D , {multTrueAxis, ptMeasAxis});
164158 }
159+
160+ trackSel = getGlobalTrackSelection ();
161+ if (cutMode == 101 ) {
162+ trackSel.SetMaxChi2PerClusterITS (25 .);
163+ cutVarFlag = TrackSelectionFlags::kITSChi2NDF ;
164+ trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF ;
165+ } else if (cutMode == 102 ) {
166+ trackSel.SetMaxChi2PerClusterITS (49 .);
167+ cutVarFlag = TrackSelectionFlags::kITSChi2NDF ;
168+ trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF ;
169+ } else if (cutMode == 103 ) {
170+ trackSel.SetMaxChi2PerClusterTPC (3.0 );
171+ cutVarFlag = TrackSelectionFlags::kTPCChi2NDF ;
172+ trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF ;
173+ } else if (cutMode == 104 ) {
174+ trackSel.SetMaxChi2PerClusterTPC (5.0 );
175+ cutVarFlag = TrackSelectionFlags::kTPCChi2NDF ;
176+ trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF ;
177+ } else if (cutMode == 105 ) {
178+ trackSel.SetMinNCrossedRowsOverFindableClustersTPC (0.7 );
179+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls ;
180+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls ;
181+ } else if (cutMode == 106 ) {
182+ trackSel.SetMinNCrossedRowsOverFindableClustersTPC (0.9 );
183+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls ;
184+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls ;
185+ } else if (cutMode == 111 ) {
186+ trackSel.SetMaxDcaXYPtDep ([](float pt) { return 4 . / 7 . * (0 .0105f + 0 .0350f / pow (pt, 1 .1f )); });
187+ cutVarFlag = TrackSelectionFlags::kDCAxy ;
188+ trackSelFlag = TrackSelection::TrackCuts::kDCAxy ;
189+ } else if (cutMode == 112 ) {
190+ trackSel.SetMaxDcaXYPtDep ([](float pt) { return 10 . / 7 . * (0 .0105f + 0 .0350f / pow (pt, 1 .1f )); });
191+ cutVarFlag = TrackSelectionFlags::kDCAxy ;
192+ trackSelFlag = TrackSelection::TrackCuts::kDCAxy ;
193+ } else if (cutMode == 113 ) {
194+ trackSel.SetMaxDcaZ (1.0 );
195+ cutVarFlag = TrackSelectionFlags::kDCAz ;
196+ trackSelFlag = TrackSelection::TrackCuts::kDCAz ;
197+ } else if (cutMode == 114 ) {
198+ trackSel.SetMaxDcaZ (5.0 );
199+ cutVarFlag = TrackSelectionFlags::kDCAz ;
200+ trackSelFlag = TrackSelection::TrackCuts::kDCAz ;
201+ } else if (cutMode == 115 ) {
202+ trackSel.ResetITSRequirements ();
203+ cutVarFlag = TrackSelectionFlags::kITSHits ;
204+ trackSelFlag = TrackSelection::TrackCuts::kITSHits ;
205+ } else if (cutMode == 116 ) {
206+ trackSel.SetMinNCrossedRowsTPC (60 );
207+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRows ;
208+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows ;
209+ } else if (cutMode == 117 ) {
210+ trackSel.SetMinNCrossedRowsTPC (80 );
211+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRows ;
212+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows ;
213+ }
214+ trackSelMask &= (~cutVarFlag);
165215}
166216
167217// **************************************************************************************************
@@ -249,7 +299,11 @@ bool chargedSpectra::initTrack(const T& track)
249299 if (track.pt () <= ptMinCut || track.pt () >= ptMaxCut) {
250300 return false ;
251301 }
252- if (!track.isGlobalTrackWoPtEta ()) {
302+ if (!TrackSelectionFlags::checkFlag (track.trackCutFlag (), trackSelMask)) {
303+ return false ;
304+ }
305+ // for systematic variation of standard selections, check if the varied cut is passed
306+ if (cutVarFlag && !trackSel.IsSelected (track, trackSelFlag)) {
253307 return false ;
254308 }
255309 return true ;
0 commit comments