|
| 1 | +--- |
| 2 | +sort: 3 |
| 3 | +title: Track selection and propagation |
| 4 | +--- |
| 5 | + |
| 6 | +# Track selection and propagation |
| 7 | + |
| 8 | +## Track Selection |
| 9 | + |
| 10 | +The track selection in the O2 analysis framework is provided in form of a stand-alone workflow that you can run in front of your analysis: |
| 11 | + |
| 12 | +``` bash |
| 13 | +o2-analysis-trackselection | o2-analysis-myTask |
| 14 | +``` |
| 15 | + |
| 16 | +Based on a set of track quality criteria, the track selection workflow produces a flag. |
| 17 | +Provided that the user uses the standard supported `o2-analysis-trackselection` track tables can be filtered, e.g. by requiring global tracks (with cuts on pT and eta), in the following manner: |
| 18 | + |
| 19 | +``` c++ |
| 20 | +#include "Analysis/TrackSelectionTables.h" |
| 21 | + ... |
| 22 | +// NB: this only works provided that you use the supported task o2-analysis-trackselection to perform the track selection |
| 23 | +Filter filter1 = requireTrackCutInFilter(TrackSelectionFlags::kTPCNCls); // General filter, defined using flags |
| 24 | +Filter filter2 = requireQualityTracksInFilter(); // Predefined filter, for kQualityTracks tracks |
| 25 | +Filter filter3 = requirePrimaryTracksInFilter(); // Predefined filter, for kPrimaryTracks tracks |
| 26 | +Filter filter4 = requireInAcceptanceTracksInFilter(); // Predefined filter, for kInAcceptanceTracks tracks |
| 27 | +Filter filter5 = requireGlobalTrackInFilter(); // Predefined filter, for kGlobalTrack tracks |
| 28 | +Filter filter6 = requireGlobalTrackWoPtEtaInFilter(); // Predefined filter, for kGlobalTrackWoPtEta tracks |
| 29 | +Filter filter7 = requireGlobalTrackWoDCAInFilter(); // Predefined filter, for kGlobalTrackWoDCA tracks |
| 30 | +Filter filter8 = requireTrackWithinBeamPipe(); // Tracks starting from within the beam pipe |
| 31 | + |
| 32 | +void process(soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection>>::iterator const& track) |
| 33 | +{ |
| 34 | + ... |
| 35 | +} |
| 36 | + |
| 37 | +``` |
| 38 | +
|
| 39 | +In general it is advised to use the filter decisions only in the filter expressions, so the framework can optimize the processing. |
| 40 | +However, if really needed you can also access the filtering decisions in the following way: |
| 41 | +
|
| 42 | +``` c++ |
| 43 | +#include "Analysis/TrackSelectionTables.h" |
| 44 | + ... |
| 45 | +
|
| 46 | +void process(soa::Join<aod::Tracks, aod::TrackSelection>::iterator const& track) |
| 47 | +{ |
| 48 | + // Check single cuts |
| 49 | + track.passedTrackType(); // Passed the track cut: kTrackType |
| 50 | + track.passedPtRange(); // Passed the track cut: kPtRange |
| 51 | + track.passedEtaRange(); // Passed the track cut: kEtaRange |
| 52 | + track.passedTPCNCls(); // Passed the track cut: kTPCNCls |
| 53 | + track.passedTPCCrossedRows(); // Passed the track cut: kTPCCrossedRows |
| 54 | + track.passedTPCCrossedRowsOverNCls();// Passed the track cut: kTPCCrossedRowsOverNCls |
| 55 | + track.passedTPCChi2NDF(); // Passed the track cut: kTPCChi2NDF |
| 56 | + track.passedTPCRefit(); // Passed the track cut: kTPCRefit |
| 57 | + track.passedITSNCls(); // Passed the track cut: kITSNCls |
| 58 | + track.passedITSChi2NDF(); // Passed the track cut: kITSChi2NDF |
| 59 | + track.passedITSRefit(); // Passed the track cut: kITSRefit |
| 60 | + track.passedITSHits(); // Passed the track cut: kITSHits |
| 61 | + track.passedGoldenChi2(); // Passed the track cut: kGoldenChi2 |
| 62 | + track.passedDCAxy(); // Passed the track cut: kDCAxy |
| 63 | + track.passedDCAz(); // Passed the track cut: kDCAz |
| 64 | + // Check combiation of cuts (filterbit like) |
| 65 | + track.isQualityTrack(); // Passed the combined track cut: kQualityTracks |
| 66 | + track.isPrimaryTrack(); // Passed the combined track cut: kPrimaryTracks |
| 67 | + track.isInAcceptanceTrack(); // Passed the combined track cut: kInAcceptanceTracks |
| 68 | + track.isGlobalTrack(); // Passed the combined track cut: kGlobalTrack |
| 69 | + track.isGlobalTrackWoPtEta(); // Passed the combined track cut: kGlobalTrackWoPtEta |
| 70 | + track.isGlobalTrackWoDCA(); // Passed the combined track cut: kGlobalTrackWoDCA |
| 71 | +} |
| 72 | +
|
| 73 | +``` |
| 74 | + |
| 75 | +Some of the track parameters used in the track selection require additional calculation effort and are then stored in a table called ```TracksExtended``` which is produced by either the ```o2-analysis-trackextension``` task (Run 2) or ```o2-analysis-track-propagation``` (Run 3). |
| 76 | +The quantities contained in this table can also be directly used in the analysis. |
| 77 | +For instance if you require the distance of closest approach (dca) to the primary vertex, you do not need to (and should not!) re-calculate it in your task. |
| 78 | +You can simply obtain it by extending the ``` Tracks ``` table in the following way and then access it directly as a property of the track: |
| 79 | + |
| 80 | +``` c++ |
| 81 | +void process(soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksDCA>>::iterator const& track) |
| 82 | +{ |
| 83 | + track.dcaXY(); |
| 84 | + track.dcaZ(); |
| 85 | +} |
| 86 | +``` |
| 87 | +
|
| 88 | +Both the definition of `TrackSelection` and the `TracksDCA` tables can be found here: [`TrackSelectionTables`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/DataModel/TrackSelectionTables.h). |
| 89 | +If you want to have a look at the track parameters after the selection, you can use the [`o2-analysis-qa-event-track`](https://github.com/AliceO2Group/O2Physics/blob/master/DPG/Tasks/AOTTrack/qaEventTrack.h) task: |
| 90 | +
|
| 91 | +``` bash |
| 92 | +o2-analysis-trackselection | o2-analysis-qa-event-track | ... |
| 93 | +``` |
| 94 | + |
| 95 | +At the moment there are two 'FilterBits' available in the TrackSelection table, which are defined as follows: |
| 96 | + |
| 97 | + | Cuts | globalTrack | globalTrackSDD | |
| 98 | + |------------------------------------------------------|------------------------------------------------------------------------|----------------------------------------------| |
| 99 | + | min number of crossed rows TPC | 70 | 70 | |
| 100 | + | min ratio of crossed rows over findable clusters TPC | 0.8 | 0.8 | |
| 101 | + | max chi2 per cluster TPC | 4.0 | 4.0 | |
| 102 | + | max chi2 per cluster ITS | 36.0 | 36.0 | |
| 103 | + | require TPC refit | true | true | |
| 104 | + | require ITS refit | true | true | |
| 105 | + | max DCA to vertex z | 2.0 | 2.0 | |
| 106 | + | max DCA to vertex xy | 0.0105 + 0.035 / p<sub>T</sub><sup>1.1</sup> | 0.0105 + 0.035 / p<sub>T</sub><sup>1.1</sup> | |
| 107 | + | cluster requirement ITS | Run 2 (Run 3): at least one hit in SPD (in 3 innermost ITS layers) [*] | no hit in SPD and hit in first SDD layer | |
| 108 | + | p<sub>T</sub> range | 0.1 - 1e10 | 0.1 - 1e10 | |
| 109 | + | η range | -0.8 - 0.8 | -0.8 - 0.8 | |
| 110 | + |
| 111 | +```note |
| 112 | +[*] |
| 113 | +
|
| 114 | +_RUN2 data/MC analyses_ (`isRun3 == false`) |
| 115 | +The default set of global-track selections requires at least 1 hit between the two innermost ITS layers (function `getGlobalTrackSelection` in [`TrackSelectionDefaults.h`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/Core/TrackSelectionDefaults.h)). |
| 116 | +This is a Run 1, 2 refuse when the SPD was equipped, and currently this is enabled ONLY for analyses on Run2 converted data (`isRun3 == false`). |
| 117 | +
|
| 118 | +_RUN3 data/MC analyses_ (`isRun3 == true`) |
| 119 | +The same set of global-track selections, but with different ITS requirements for Run3 data are available in [`trackselection.cxx`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackselection.cxx). This is possible thanks to the `getGlobalTrackSelectionITSMatch` in [`TrackSelectionDefaults.h`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/Core/TrackSelectionDefaults.h), which can be enabled with different ITS requirements via the integer configurable `itsMatching` in [`trackselection.cxx`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackselection.cxx). The available configurations are the following: |
| 120 | +
|
| 121 | +* `itsMatching == 0`: at least one hit between the two innermost ITS layers (default for `isRun3 == false`). |
| 122 | + IMPORTANT: in case `isRun3 == true`, then `itsMatching == 0` enables `itsMatching == 1` automatically (a WARNING is dumped at runtime); |
| 123 | +* `itsMatching == 1`: at least one hit among the three innermost ITS layers (`Run3ITSibAny`, default for `isRun3 == true`); |
| 124 | +* `itsMatching == 2`: at least one hit among all the ITS layers (`Run3ITSallAny`); |
| 125 | +* `itsMatching == 3`: one hit on all the ITS layers (`Run3ITSall7Layers`); |
| 126 | +``` |
| 127 | + |
| 128 | +The goal of the track selection task is to provide the most common selections for all analyses. |
| 129 | +If you really require a completely different set of tracks not covered by the standard filter bits, you can create your own TrackSelection object (see [`TrackSelectionTables.h`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/DataModel/TrackSelectionTables.h) and [`trackselection.cxx`](https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackselection.cxx)) : |
| 130 | + |
| 131 | +``` c++ |
| 132 | + |
| 133 | +TrackSelection myTrackSelection() |
| 134 | +{ |
| 135 | + TrackSelection selectedTracks; |
| 136 | + selectedTracks.SetTrackType(aod::track::Run2GlobalTrack); |
| 137 | + selectedTracks.SetPtRange(0.1f, 1e10f); |
| 138 | + selectedTracks.SetEtaRange(-0.8f, 0.8f); |
| 139 | + selectedTracks.SetRequireITSRefit(true); |
| 140 | + selectedTracks.SetRequireTPCRefit(true); |
| 141 | + selectedTracks.SetRequireGoldenChi2(true); |
| 142 | + selectedTracks.SetMinNCrossedRowsTPC(70); |
| 143 | + selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(0.8f); |
| 144 | + selectedTracks.SetMaxChi2PerClusterTPC(4.f); |
| 145 | + selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); // one hit in any SPD layer |
| 146 | + selectedTracks.SetMaxChi2PerClusterITS(36.f); |
| 147 | + selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / pow(pt, 1.1f); }); |
| 148 | + selectedTracks.SetMaxDcaZ(2.f); |
| 149 | + ... |
| 150 | + return selectedTracks; |
| 151 | +} |
| 152 | + |
| 153 | +... |
| 154 | + |
| 155 | +// member of analysis task |
| 156 | +TrackSelection mySelection; |
| 157 | + |
| 158 | +... |
| 159 | + |
| 160 | +// in init() |
| 161 | +mySelection = myTrackSelection(); |
| 162 | + |
| 163 | +... |
| 164 | + |
| 165 | +// in process() |
| 166 | +bool isSelected = mySelection.IsSelected(track) |
| 167 | +``` |
| 168 | + |
| 169 | +### Remarks on track selection |
| 170 | + |
| 171 | +Please note that this documentation only represents the status quo of the track selection implementation and many things can and will change. |
| 172 | +In particular the cut values will most likely change with the 'new' detector in Run 3 and some of the legacy cuts will be removed or only available for converted Run 2 data. |
| 173 | +In case of questions or suggestions don't hesitate to contact us. |
| 174 | + |
| 175 | +## Track Propagation |
| 176 | + |
| 177 | +The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the |
| 178 | +innermost (or second innermost) ITS layer. For a track without ITS, this is the TPC inner wall or |
| 179 | +for loopers in the TPC even a radius beyond that. In the AO2D.root the trees are therefore called O2tracks_IU |
| 180 | +and O2tracksCov_IU (IU = innermost update). The corresponding O2 data model tables are TracksIU and TracksCovIU, respectively. |
| 181 | +If your task needs tracks at the collision vertex it will fail because it looks for O2tracks and O2tracksCov. |
| 182 | + |
| 183 | +In order to propagate the tracks to the collision vertex, include the task `o2-analysis-track-propagation` into your workflow. |
| 184 | +This task produces the tables Tracks and TracksCov (in order to get the latter, please enable `processCovariance` through the json configuration). |
| 185 | + |
| 186 | +```note |
| 187 | +This task also produces the `TrackExtended` table needed for `o2-analysis-track-selection`, therefore `o2-analysis-trackextension` does not need to be added to the workflow at the same time. |
| 188 | +``` |
| 189 | + |
| 190 | +This task is not needed for Run 2 converted data where the tracks are already propagated to the collision vertex. |
| 191 | + |
| 192 | +The overall table flow is illustrated here: |
| 193 | + |
| 194 | +<div align="center"> |
| 195 | +<img src="prop.png" width="60%"> |
| 196 | +</div> |
| 197 | + |
| 198 | + |
| 199 | +## The TrackTuner class |
| 200 | +The `TrackTuner` class ([Common/Tools/TrackTuner.h](https://github.com/AliceO2Group/O2Physics/blob/master/Common/Tools/TrackTuner.h)) allows to smear the reconstructed track parameters. |
| 201 | +Such tool is primarely conceived to smear the parameters of tracks reconstructed in MC simulations according to the discrepancy between data and MC of the dcaXY and dcaZ. |
| 202 | +```note |
| 203 | +This task was called `improver-task` in the Run 2 jargon |
| 204 | +``` |
| 205 | +The smearing is done on the `y`, `z` parameters of each reconstructed track in MC evaluated at the associated particle production point. The smearing is based on the discrepancy between resolution, mean and pull ratio of dcaXY, dcaZ w.r.t. primary vertex measured in data and MC. |
| 206 | +The performance of such parameters is evaluated vs. global-track pt and stored into `.root` files, which can be read from CCDB at runtime. |
| 207 | + |
| 208 | +An instance of the `TrackTuner` class is present as data-member in the `trackPropagation` workflow, and it can be enabled via |
| 209 | +```c++ |
| 210 | +Configurable<bool> useTrackTuner{"useTrackTuner", false, "Apply Improver/DCA corrections to MC"}; |
| 211 | +``` |
| 212 | +```note |
| 213 | +The `TrackTuner` can be enabled only if the `processCovarianceMc` process function in the `trackPropagation` workflow is used |
| 214 | +``` |
| 215 | +This object can be configured through the `Configurable<std::string> trackTunerParams` in the `trackPropagation` workflow. This configuration `std::string` must define the following parameters: |
| 216 | +* `bool debugInfo`: flag to switch on/off some debug outputs |
| 217 | +* `bool updateTrackDCAs`: flag to switch on/off the smearing of the dcaXY, dcaZ |
| 218 | +* `bool updateTrackCovMat`: flag to enable the update of the track covariance matrix, propagating the scaling on the dca resolution |
| 219 | +* `bool updatePulls`: flag to enable the update of the track covariance matrix updating also the pulls (if `updateTrackCovMat == true`) |
| 220 | +* `std::string pathInputFile`: path to browse to find the correction file for the dca smearing |
| 221 | +* `std::string nameInputFile`: name of the correction file for the dca smearing |
| 222 | +* `bool isInputFileFromCCDB`: the `pathInputFile/nameInputFile` is searched in CCDB if this flag is `true`, otherwise in the local file system (debug purposes) |
| 223 | +* `bool usePvRefitCorrections`: if this flag is `true`, the track smearing is performed using mean, resolution and pulls parametrizations vs. pt of dcaXY, dcaZ calculated w.r.t. primary collision vertex refitted w/o the current track, if this was originally a PV contributor |
| 224 | +```note |
| 225 | +In pp collisions, there is a difference between `usePvRefitCorrections == true` and `usePvRefitCorrections == false`. In the former case, the parametrizations are obtained after refitting the primary vertex by removing from its fit the probe track, if it was originally a contributor. |
| 226 | +This is not relevant in Pb-Pb collisions. |
| 227 | +``` |
| 228 | +* `std::string pathFileQoverPt`: path to browse to find the correction file for the `q/pt` smearing |
| 229 | +* `std::string nameFileQoverPt`: name of the correction file for the `q/pt` smearing |
| 230 | +* `bool updateCurvature`: flag to enable the update of the track curvature, i.e. `q/pt`, at the particle production point |
| 231 | +* `bool updateCurvatureIU`: flag to enable the update of the track curvature, i.e. `q/pt`, at the innermost update (IU) point |
| 232 | +* `float oneOverPtMC` (MC) and `float oneOverPtData` (data): the ratio `oneOverPtData/oneOverPtMC` defines the scaling factor to the `q/pt` residual to smear the track pt |
| 233 | +* `bool fillTrackTunerTable`: flag to enable the filling of a new table containing for each track the smeared `q/pt` at the IU point |
| 234 | +* `int nPhiBins`: number of phi intervals in which the parametrizations are provided. The currently-supported cases are `nPhiBins=0` (phi integrated) and `nPhiBins=24` (24 phi bins) |
| 235 | + |
| 236 | +```note |
| 237 | +* The `TrackTuner` allows also to smear the `q/pt` if only one between `updateCurvature` and `updateCurvatureIU` is `true` |
| 238 | +* By default, the variables `oneOverPtData` and `oneOverPtMC` are initialized to `-1` |
| 239 | +* If at least one between`qOverPtMCq` and `OverPtData` is negative, the `q/pt` correction is done wuering the file from CCDB. Otherwise, the input values of `qOverPtMC` and `qOverPtData` are used to defined the factor `oneOverPtData/oneOverPtMC`, which is a constant factor flat in transverse momentum. |
| 240 | +``` |
| 241 | +The string `trackTunerParams` must follow the format: `<variable_name>=<value>|<variable_name>=<value>` (see the default configuration [here](https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackPropagation.cxx#L62) as reference). |
| 242 | + |
| 243 | + |
| 244 | +The dcaXY, dcaZ parametrization currently available are the following: |
| 245 | +* proxy for pp @ 13.6 TeV: [trackTuner_DataLHC23hPass4_McLHC23k4g.root](http://alice-ccdb.cern.ch/browse/Users/m/mfaggin/test/inputsTrackTuner/pp2023/pass4/correct_names) |
| 246 | + Data: LHC23h apass4. |
| 247 | + MC: LHC23k4g. |
| 248 | + Slides [here](https://docs.google.com/presentation/d/10d1fE7Dh7OukTNgwwOhS8JQCEqzWZ3yjYZmpjntTDWw/edit?usp=sharing). |
| 249 | +* proxy for pp @ 13.6 TeV in 24 phi intervals: [trackTuner_DataLHC23pass4ThinSmall_McLHC23k4gSmall.root](http://alice-ccdb.cern.ch/browse/Users/m/mfaggin/test/inputsTrackTuner/pp2023/pass4/vsPhi) |
| 250 | + Data: LHC23_pass4_thin_small, runs 535613, 535621, 535623, 535624, 535627, 535644, 535645, 535711, 535716, 535721, 535725 |
| 251 | + MC: LHC24k4g_small, runs 535613, 535621, 535623, 535624, 535627, 535644, 535645, 535711, 535716, 535721, 535722, 535725 |
| 252 | + Slides [here](https://docs.google.com/presentation/d/1JL8nHY7yJ-PhCqTNTJq8y3dHm5XLe3Nd4bT27yjp97U/edit?usp=sharing) |
| 253 | +* proxy for Pb-Pb @ 5.36 TeV: [trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root](http://alice-ccdb.cern.ch/browse/Users/m/mfaggin/test/inputsTrackTuner/PbPb2022) |
| 254 | + Data: LHC22s apass5, run 529397. |
| 255 | + MC: LHC22l1b2, run 529397. |
| 256 | + Slides [here](https://docs.google.com/presentation/d/1sIXWMckaPZJir3gNLeDnB2TorNJrjXKcGJvyTvz5V8s/edit?usp=sharing). |
| 257 | +* proxy for PbPb @ 5.36 TeV in 24 phi intervals: [trackTuner_DataLHC24zzh_apass4_McLHC24e2_MCflat13.root](http://alice-ccdb.cern.ch/browse/Users/m/mfaggin/test/inputsTrackTuner/PbPb2023/apass4/vsPhi) |
| 258 | + Data: LHC23zzh_apass4 |
| 259 | + MC: LHC24e2 |
0 commit comments