99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
1111
12- // 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
14-
15- #include " Framework/HistogramRegistry.h"
16- #include " ReconstructionDataFormats/Track.h"
17- #include " Framework/runDataProcessing.h"
18- #include " Framework/AnalysisTask.h"
19- #include " Framework/O2DatabasePDGPlugin.h"
20- #include " Common/DataModel/EventSelection.h"
12+ // / \file chargedParticles.cxx
13+ // / \brief Task for analysis of charged particle pt spectra vs multiplicity with 2d unfolding.
14+ // / \author Mario Krüger <mario.kruger@cern.ch>
15+
16+ #include " Common/Core/TrackSelection.h"
17+ #include " Common/Core/TrackSelectionDefaults.h"
2118#include " Common/DataModel/Centrality.h"
19+ #include " Common/DataModel/EventSelection.h"
2220#include " Common/DataModel/TrackSelectionTables.h"
23- #include " TDatabasePDG.h"
21+
22+ #include < Framework/AnalysisTask.h>
23+ #include < Framework/HistogramRegistry.h>
24+ #include < Framework/O2DatabasePDGPlugin.h>
25+ #include < Framework/runDataProcessing.h>
26+ #include < ReconstructionDataFormats/Track.h>
27+
28+ #include < unordered_set>
29+ #include < vector>
2430
2531using namespace o2 ;
2632using namespace o2 ::framework;
33+ using aod::track::TrackSelectionFlags;
2734
2835// --------------------------------------------------------------------------------------------------
2936// --------------------------------------------------------------------------------------------------
3037// Task declaration
3138// --------------------------------------------------------------------------------------------------
3239// --------------------------------------------------------------------------------------------------
33- struct chargedSpectra {
40+ struct ChargedParticles {
3441
3542 HistogramRegistry histos;
3643 Service<o2::framework::O2DatabasePDG> pdg;
3744
38- // task settings that can be steered via hyperloop
3945 Configurable<bool > isRun3{" isRun3" , true , " is Run3 dataset" };
4046 Configurable<uint32_t > maxMultMeas{" maxMultMeas" , 100 , " max measured multiplicity" };
4147 Configurable<uint32_t > maxMultTrue{" maxMultTrue" , 100 , " max true multiplicity" };
4248 Configurable<float > etaCut{" etaCut" , 0 .8f , " eta cut" };
4349 Configurable<float > ptMinCut{" ptMinCut" , 0 .15f , " pt min cut" };
4450 Configurable<float > ptMaxCut{" ptMaxCut" , 10 .f , " pt max cut" };
45-
4651 Configurable<bool > normINELGT0{" normINELGT0" , false , " normalize INEL>0 according to MC" };
4752
53+ enum : uint32_t {
54+ kSystNominal = 100 ,
55+ kSystDownChi2PerClusterITS ,
56+ kSystUpChi2PerClusterITS ,
57+ kSystDownChi2PerClusterTPC ,
58+ kSystUpChi2PerClusterTPC ,
59+ kSystDownTPCCrossedRowsOverNCls ,
60+ kSystUpTPCCrossedRowsOverNCls ,
61+ kSystDownDCAxy = 111 ,
62+ kSystUpDCAxy ,
63+ kSystDownDCAz ,
64+ kSystUpDCAz ,
65+ kSystITSHits ,
66+ kSystDownTPCCrossedRows ,
67+ kSystUpTPCCrossedRows
68+ };
69+ Configurable<uint32_t > systMode{" systMode" , kSystNominal , " variation for systematic uncertainties" };
70+ uint16_t trackSelMask{TrackSelectionFlags::kGlobalTrackWoPtEta }; // track selection bitmask (without cut that is being varied)
71+ uint16_t cutVarFlag{0 };
72+ TrackSelection trackSel;
73+ TrackSelection::TrackCuts trackSelFlag;
74+
4875 // helper struct to store transient properties
49- struct varContainer {
76+ struct VarContainer {
5077 uint32_t multMeas{0u };
5178 uint32_t multTrue{0u };
5279 bool isAcceptedEvent{false };
5380 bool isAcceptedEventMC{false };
5481 bool isINELGT0EventMC{false };
5582 bool isChargedPrimary{false };
5683 };
57- varContainer vars;
84+ VarContainer vars;
85+ static constexpr float kMaxVtxZ = 10 .f;
5886
5987 void init (InitContext const &);
6088
@@ -70,43 +98,29 @@ struct chargedSpectra {
7098 template <typename C, typename P>
7199 void initEventMC (const C& collision, const P& particles);
72100
73- template <bool IS_MC, typename C, typename T>
74- void processMeas (const C& collision, const T& tracks);
101+ template <bool IS_MC, typename T>
102+ void processMeas (const T& tracks);
75103
76- template <typename C, typename P>
77- void processTrue (const C& collision, const P& particles);
104+ template <typename P>
105+ void processTrue (const P& particles);
78106
79107 using CollisionTableData = soa::Join<aod::Collisions, aod::EvSels>;
80- using TrackTableData = soa::Join<aod::Tracks , aod::TrackSelection>;
108+ using TrackTableData = soa::Join<aod::FullTracks, aod::TracksDCA , aod::TrackSelection>;
81109 void processData (CollisionTableData::iterator const & collision, TrackTableData const & tracks);
82- PROCESS_SWITCH (chargedSpectra , processData, " process data" , false );
110+ PROCESS_SWITCH (ChargedParticles , processData, " process data" , false );
83111
84112 using CollisionTableMCTrue = aod::McCollisions;
85113 using CollisionTableMC = soa::SmallGroups<soa::Join<aod::McCollisionLabels, aod::Collisions, aod::EvSels>>;
86- using TrackTableMC = soa::Join<aod::Tracks , aod::McTrackLabels , aod::TrackSelection>;
114+ using TrackTableMC = soa::Join<aod::FullTracks , aod::TracksDCA , aod::TrackSelection, aod::McTrackLabels >;
87115 using ParticleTableMC = aod::McParticles;
88116 Preslice<TrackTableMC> perCollision = aod::track::collisionId;
89117 void processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks, ParticleTableMC const & particles);
90- 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- */
118+ PROCESS_SWITCH (ChargedParticles, processMC, " process mc" , true );
105119};
106120
107121WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
108122{
109- return WorkflowSpec{adaptAnalysisTask<chargedSpectra >(cfgc)};
123+ return WorkflowSpec{adaptAnalysisTask<ChargedParticles >(cfgc)};
110124}
111125
112126// --------------------------------------------------------------------------------------------------
@@ -120,7 +134,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
120134 * Initialise the task and add histograms.
121135 */
122136// **************************************************************************************************
123- void chargedSpectra ::init (InitContext const &)
137+ void ChargedParticles ::init (InitContext const &)
124138{
125139 std::vector<double > ptBinEdges = {0.15 , 0.2 , 0.25 , 0.3 , 0.35 , 0.4 , 0.45 , 0.5 , 0.55 , 0.6 , 0.65 , 0.7 , 0.75 ,
126140 0.8 , 0.85 , 0.9 , 0.95 , 1.0 , 1.1 , 1.2 , 1.3 , 1.4 , 1.5 , 1.6 , 1.7 , 1.8 , 1.9 ,
@@ -162,25 +176,81 @@ void chargedSpectra::init(InitContext const&)
162176 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
163177 histos.add (" multPtSpec_trk_inter" , " " , kTH2D , {multTrueAxis, ptMeasAxis});
164178 }
179+
180+ trackSel = getGlobalTrackSelection ();
181+ if (systMode == kSystDownChi2PerClusterITS ) {
182+ trackSel.SetMaxChi2PerClusterITS (25 .);
183+ cutVarFlag = TrackSelectionFlags::kITSChi2NDF ;
184+ trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF ;
185+ } else if (systMode == kSystUpChi2PerClusterITS ) {
186+ trackSel.SetMaxChi2PerClusterITS (49 .);
187+ cutVarFlag = TrackSelectionFlags::kITSChi2NDF ;
188+ trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF ;
189+ } else if (systMode == kSystDownChi2PerClusterTPC ) {
190+ trackSel.SetMaxChi2PerClusterTPC (3.0 );
191+ cutVarFlag = TrackSelectionFlags::kTPCChi2NDF ;
192+ trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF ;
193+ } else if (systMode == kSystUpChi2PerClusterTPC ) {
194+ trackSel.SetMaxChi2PerClusterTPC (5.0 );
195+ cutVarFlag = TrackSelectionFlags::kTPCChi2NDF ;
196+ trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF ;
197+ } else if (systMode == kSystDownTPCCrossedRowsOverNCls ) {
198+ trackSel.SetMinNCrossedRowsOverFindableClustersTPC (0.7 );
199+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls ;
200+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls ;
201+ } else if (systMode == kSystUpTPCCrossedRowsOverNCls ) {
202+ trackSel.SetMinNCrossedRowsOverFindableClustersTPC (0.9 );
203+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls ;
204+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls ;
205+ } else if (systMode == kSystDownDCAxy ) {
206+ trackSel.SetMaxDcaXYPtDep ([](float pt) { return 4 . / 7 . * (0 .0105f + 0 .0350f / std::pow (pt, 1 .1f )); });
207+ cutVarFlag = TrackSelectionFlags::kDCAxy ;
208+ trackSelFlag = TrackSelection::TrackCuts::kDCAxy ;
209+ } else if (systMode == kSystUpDCAxy ) {
210+ trackSel.SetMaxDcaXYPtDep ([](float pt) { return 10 . / 7 . * (0 .0105f + 0 .0350f / std::pow (pt, 1 .1f )); });
211+ cutVarFlag = TrackSelectionFlags::kDCAxy ;
212+ trackSelFlag = TrackSelection::TrackCuts::kDCAxy ;
213+ } else if (systMode == kSystDownDCAz ) {
214+ trackSel.SetMaxDcaZ (1.0 );
215+ cutVarFlag = TrackSelectionFlags::kDCAz ;
216+ trackSelFlag = TrackSelection::TrackCuts::kDCAz ;
217+ } else if (systMode == kSystUpDCAz ) {
218+ trackSel.SetMaxDcaZ (5.0 );
219+ cutVarFlag = TrackSelectionFlags::kDCAz ;
220+ trackSelFlag = TrackSelection::TrackCuts::kDCAz ;
221+ } else if (systMode == kSystITSHits ) {
222+ trackSel.ResetITSRequirements ();
223+ cutVarFlag = TrackSelectionFlags::kITSHits ;
224+ trackSelFlag = TrackSelection::TrackCuts::kITSHits ;
225+ } else if (systMode == kSystDownTPCCrossedRows ) {
226+ trackSel.SetMinNCrossedRowsTPC (60 );
227+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRows ;
228+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows ;
229+ } else if (systMode == kSystUpTPCCrossedRows ) {
230+ trackSel.SetMinNCrossedRowsTPC (80 );
231+ cutVarFlag = TrackSelectionFlags::kTPCCrossedRows ;
232+ trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows ;
233+ }
234+ trackSelMask &= (~cutVarFlag);
165235}
166236
167237// **************************************************************************************************
168238/* *
169239 * Entrypoint to processes data.
170240 */
171241// **************************************************************************************************
172- void chargedSpectra ::processData (CollisionTableData::iterator const & collision, TrackTableData const & tracks)
242+ void ChargedParticles ::processData (CollisionTableData::iterator const & collision, TrackTableData const & tracks)
173243{
174244 initEvent (collision, tracks);
175- processMeas<false >(collision, tracks);
245+ processMeas<false >(tracks);
176246}
177247
178248// **************************************************************************************************
179249/* *
180250 * Entrypoint to processes mc.
181251 */
182252// **************************************************************************************************
183- void chargedSpectra ::processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks, ParticleTableMC const & particles)
253+ void ChargedParticles ::processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks, ParticleTableMC const & particles)
184254{
185255 histos.fill (HIST (" collision_ambiguity" ), collisions.size ());
186256
@@ -198,14 +268,14 @@ void chargedSpectra::processMC(CollisionTableMCTrue::iterator const& mcCollision
198268 if (collisions.size () == 0 ) {
199269 vars.isAcceptedEvent = false ;
200270 } else {
201- for (auto & collision : collisions) {
271+ for (const auto & collision : collisions) {
202272 auto curTracks = tracks.sliceBy (perCollision, collision.globalIndex ());
203273 initEvent (collision, curTracks);
204- processMeas<true >(collision, curTracks);
274+ processMeas<true >(curTracks);
205275 break ; // for now look only at first collision...
206276 }
207277 }
208- processTrue (mcCollision, particles);
278+ processTrue (particles);
209279}
210280
211281// **************************************************************************************************
@@ -214,7 +284,7 @@ void chargedSpectra::processMC(CollisionTableMCTrue::iterator const& mcCollision
214284 */
215285// **************************************************************************************************
216286template <typename P>
217- bool chargedSpectra ::initParticle (const P& particle)
287+ bool ChargedParticles ::initParticle (const P& particle)
218288{
219289 vars.isChargedPrimary = false ;
220290 auto pdgParticle = pdg->GetParticle (particle.pdgCode ());
@@ -241,15 +311,19 @@ bool chargedSpectra::initParticle(const P& particle)
241311 */
242312// **************************************************************************************************
243313template <typename T>
244- bool chargedSpectra ::initTrack (const T& track)
314+ bool ChargedParticles ::initTrack (const T& track)
245315{
246316 if (std::abs (track.eta ()) >= etaCut) {
247317 return false ;
248318 }
249319 if (track.pt () <= ptMinCut || track.pt () >= ptMaxCut) {
250320 return false ;
251321 }
252- if (!track.isGlobalTrackWoPtEta ()) {
322+ if (!TrackSelectionFlags::checkFlag (track.trackCutFlag (), trackSelMask)) {
323+ return false ;
324+ }
325+ // for systematic variation of standard selections, check if the varied cut is passed
326+ if (cutVarFlag && !trackSel.IsSelected (track, trackSelFlag)) {
253327 return false ;
254328 }
255329 return true ;
@@ -261,17 +335,17 @@ bool chargedSpectra::initTrack(const T& track)
261335 */
262336// **************************************************************************************************
263337template <typename C, typename T>
264- void chargedSpectra ::initEvent (const C& collision, const T& tracks)
338+ void ChargedParticles ::initEvent (const C& collision, const T& tracks)
265339{
266340 vars.multMeas = 0 ;
267- for (auto & track : tracks) {
341+ for (const auto & track : tracks) {
268342 if (initTrack (track)) {
269343 ++vars.multMeas ;
270344 }
271345 }
272346
273347 vars.isAcceptedEvent = false ;
274- if (std::abs (collision.posZ ()) < 10 . f ) {
348+ if (std::abs (collision.posZ ()) < kMaxVtxZ ) {
275349 if (isRun3 ? collision.sel8 () : collision.sel7 ()) {
276350 if ((isRun3 || doprocessMC) ? true : collision.alias_bit (kINT7 )) {
277351 vars.isAcceptedEvent = true ;
@@ -286,35 +360,35 @@ void chargedSpectra::initEvent(const C& collision, const T& tracks)
286360 */
287361// **************************************************************************************************
288362template <typename C, typename P>
289- void chargedSpectra ::initEventMC (const C& collision, const P& particles)
363+ void ChargedParticles ::initEventMC (const C& collision, const P& particles)
290364{
291365 vars.isINELGT0EventMC = false ; // will be set to true in case a charged particle within eta +-1 is found
292366 vars.multTrue = 0 ;
293- for (auto & particle : particles) {
367+ for (const auto & particle : particles) {
294368 if (!initParticle (particle) || !vars.isChargedPrimary ) {
295369 continue ;
296370 }
297371 ++vars.multTrue ;
298372 }
299373 bool isGoodEventClass = (normINELGT0) ? vars.isINELGT0EventMC : (vars.multTrue > 0 );
300- vars.isAcceptedEventMC = isGoodEventClass && (std::abs (collision.posZ ()) < 10 . f );
374+ vars.isAcceptedEventMC = isGoodEventClass && (std::abs (collision.posZ ()) < kMaxVtxZ );
301375}
302376
303377// **************************************************************************************************
304378/* *
305379 * Function to processes MC truth info. Assumes initEvent and initEventMC have been called previously.
306380 */
307381// **************************************************************************************************
308- template <typename C, typename P>
309- void chargedSpectra ::processTrue (const C& /* collision */ , const P& particles)
382+ template <typename P>
383+ void ChargedParticles ::processTrue (const P& particles)
310384{
311385 if (!vars.isAcceptedEventMC ) {
312386 return ;
313387 }
314388
315389 histos.fill (HIST (" multDist_evt_gen" ), vars.multTrue );
316390
317- for (auto & particle : particles) {
391+ for (const auto & particle : particles) {
318392 if (initParticle (particle) && vars.isChargedPrimary ) {
319393 histos.fill (HIST (" multPtSpec_prim_gen" ), vars.multTrue , particle.pt ());
320394 if (!vars.isAcceptedEvent ) {
@@ -329,8 +403,8 @@ void chargedSpectra::processTrue(const C& /*collision*/, const P& particles)
329403 * Function to process reconstructed data and MC. Assumes initEvent (and initEventMC in case of MC) have been called previously.
330404 */
331405// **************************************************************************************************
332- template <bool IS_MC, typename C, typename T>
333- void chargedSpectra ::processMeas (const C& /* collision */ , const T& tracks)
406+ template <bool IS_MC, typename T>
407+ void ChargedParticles ::processMeas (const T& tracks)
334408{
335409 if (!vars.isAcceptedEvent ) {
336410 return ;
@@ -345,8 +419,7 @@ void chargedSpectra::processMeas(const C& /*collision*/, const T& tracks)
345419 }
346420
347421 std::vector<int > foundParticles;
348- for (auto & track : tracks) {
349-
422+ for (const auto & track : tracks) {
350423 if (!initTrack (track)) {
351424 continue ;
352425 }
@@ -390,7 +463,7 @@ void chargedSpectra::processMeas(const C& /*collision*/, const T& tracks)
390463 }
391464
392465 std::unordered_set<int > uniqueIndices (foundParticles.begin (), foundParticles.end ());
393- for (auto mcParticleID : uniqueIndices) {
466+ for (const auto & mcParticleID : uniqueIndices) {
394467 histos.fill (HIST (" track_ambiguity" ), std::count (foundParticles.begin (), foundParticles.end (), mcParticleID));
395468 }
396469}
0 commit comments