Skip to content

Commit 7d78de8

Browse files
authored
Split track extension and selection (#4640)
- Create directory for ALICE3 related studies - Add selection task for Run5 - Add method to check single cut - Add task to fill QA info for track cuts - Add header for standard cut object creation
1 parent 26da3e9 commit 7d78de8

10 files changed

Lines changed: 296 additions & 76 deletions

File tree

Analysis/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ o2_target_root_dictionary(AnalysisCore
2323
HEADERS include/Analysis/StepTHn.h
2424
include/Analysis/CorrelationContainer.h
2525
include/Analysis/TrackSelection.h
26+
include/Analysis/TrackSelectionDefaults.h
2627
include/Analysis/VarManager.h
2728
include/Analysis/HistogramManager.h
2829
include/Analysis/AnalysisCut.h

Analysis/Core/include/Analysis/TrackSelection.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ class TrackSelection
2626
public:
2727
TrackSelection() = default;
2828

29+
enum class TrackCuts : int {
30+
kTrackType = 0,
31+
kPtRange,
32+
kEtaRange,
33+
kTPCNCls,
34+
kTPCCrossedRows,
35+
kTPCCrossedRowsOverNCls,
36+
kTPCChi2NDF,
37+
kTPCRefit,
38+
kITSNCls,
39+
kITSChi2NDF,
40+
kITSRefit,
41+
kITSHits,
42+
kGoldenChi2,
43+
kDCAxy,
44+
kDCAz,
45+
kNCuts
46+
};
47+
48+
static const std::string mCutNames[static_cast<int>(TrackCuts::kNCuts)];
49+
2950
// Temporary function to check if track passes selection criteria. To be replaced by framework filters.
3051
template <typename T>
3152
bool IsSelected(T const& track)
@@ -51,6 +72,46 @@ class TrackSelection
5172
}
5273
}
5374

75+
// Temporary function to check if track passes a given selection criteria. To be replaced by framework filters.
76+
template <typename T>
77+
bool IsSelected(T const& track, const TrackCuts& cut)
78+
{
79+
switch (cut) {
80+
case TrackCuts::kTrackType:
81+
return track.trackType() == mTrackType;
82+
case TrackCuts::kPtRange:
83+
return track.pt() >= mMinPt && track.pt() <= mMaxPt;
84+
case TrackCuts::kEtaRange:
85+
return track.eta() >= mMinEta && track.eta() <= mMaxEta;
86+
case TrackCuts::kTPCNCls:
87+
return track.tpcNClsFound() >= mMinNClustersTPC;
88+
case TrackCuts::kTPCCrossedRows:
89+
return track.tpcNClsCrossedRows() >= mMinNCrossedRowsTPC;
90+
case TrackCuts::kTPCCrossedRowsOverNCls:
91+
return track.tpcCrossedRowsOverFindableCls() >= mMinNCrossedRowsOverFindableClustersTPC;
92+
case TrackCuts::kTPCChi2NDF:
93+
return track.itsNCls() >= mMinNClustersITS;
94+
case TrackCuts::kTPCRefit:
95+
return track.itsChi2NCl() <= mMaxChi2PerClusterITS;
96+
case TrackCuts::kITSNCls:
97+
return track.tpcChi2NCl() <= mMaxChi2PerClusterTPC;
98+
case TrackCuts::kITSChi2NDF:
99+
return (mRequireITSRefit) ? (track.flags() & o2::aod::track::ITSrefit) : true;
100+
case TrackCuts::kITSRefit:
101+
return (mRequireTPCRefit) ? (track.flags() & o2::aod::track::TPCrefit) : true;
102+
case TrackCuts::kITSHits:
103+
return (mRequireGoldenChi2) ? (track.flags() & o2::aod::track::GoldenChi2) : true;
104+
case TrackCuts::kGoldenChi2:
105+
return FulfillsITSHitRequirements(track.itsClusterMap());
106+
case TrackCuts::kDCAxy:
107+
return abs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY);
108+
case TrackCuts::kDCAz:
109+
return abs(track.dcaZ()) <= mMaxDcaZ;
110+
default:
111+
return false;
112+
}
113+
}
114+
54115
void SetTrackType(o2::aod::track::TrackTypeEnum trackType) { mTrackType = trackType; }
55116
void SetPtRange(float minPt = 0.f, float maxPt = 1e10f)
56117
{
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
///
12+
/// \file TrackSelectionDefaults.h
13+
/// \brief Class for the definition of standard track selection objects
14+
/// \since 20-10-2020
15+
///
16+
17+
#ifndef TrackSelectionDefaults_H
18+
#define TrackSelectionDefaults_H
19+
20+
#include "Framework/DataTypes.h"
21+
22+
// Default track selection requiring one hit in the SPD
23+
TrackSelection getGlobalTrackSelection()
24+
{
25+
TrackSelection selectedTracks;
26+
selectedTracks.SetTrackType(o2::aod::track::Run2GlobalTrack);
27+
selectedTracks.SetPtRange(0.1f, 1e10f);
28+
selectedTracks.SetEtaRange(-0.8f, 0.8f);
29+
selectedTracks.SetRequireITSRefit(true);
30+
selectedTracks.SetRequireTPCRefit(true);
31+
selectedTracks.SetRequireGoldenChi2(true);
32+
selectedTracks.SetMinNCrossedRowsTPC(70);
33+
selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(0.8f);
34+
selectedTracks.SetMaxChi2PerClusterTPC(4.f);
35+
selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); // one hit in any SPD layer
36+
selectedTracks.SetMaxChi2PerClusterITS(36.f);
37+
selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / pow(pt, 1.1f); });
38+
selectedTracks.SetMaxDcaZ(2.f);
39+
return selectedTracks;
40+
}
41+
42+
// Default track selection requiring no hit in the SPD and one in the innermost
43+
// SDD -> complementary tracks to global selection
44+
TrackSelection getGlobalTrackSelectionSDD()
45+
{
46+
TrackSelection selectedTracks = getGlobalTrackSelection();
47+
selectedTracks.ResetITSRequirements();
48+
selectedTracks.SetRequireNoHitsInITSLayers({0, 1}); // no hit in SPD layers
49+
selectedTracks.SetRequireHitsInITSLayers(1, {2}); // one hit in first SDD layer
50+
return selectedTracks;
51+
}
52+
53+
#endif

Analysis/Core/src/TrackSelection.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ bool TrackSelection::FulfillsITSHitRequirements(uint8_t itsClusterMap)
2626
}
2727
}
2828
return true;
29-
};
29+
}
30+
31+
const std::string TrackSelection::mCutNames[static_cast<int>(TrackSelection::TrackCuts::kNCuts)] = {"TrackType", "PtRange", "EtaRange", "TPCNCls", "TPCCrossedRows", "TPCCrossedRowsOverNCls", "TPCChi2NDF", "TPCRefit", "ITSNCls", "ITSChi2NDF", "ITSRefit", "ITSHits", "GoldenChi2", "DCAxy", "DCAz"};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright CERN and copyright holders of ALICE O2. This software is distributed
2+
# under the terms of the GNU General Public License v3 (GPL Version 3), copied
3+
# verbatim in the file "COPYING".
4+
#
5+
# See http://alice-o2.web.cern.ch/license for full licensing information.
6+
#
7+
# In applying this license CERN does not waive the privileges and immunities
8+
# granted to it by virtue of its status as an Intergovernmental Organization or
9+
# submit itself to any jurisdiction.
10+
11+
o2_add_dpl_workflow(alice3-trackselection
12+
SOURCES alice3-trackselection.cxx
13+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore
14+
COMPONENT_NAME Analysis)
15+
16+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
//
12+
// Task performing basic track selection.
13+
//
14+
15+
#include "Framework/AnalysisDataModel.h"
16+
#include "Framework/AnalysisTask.h"
17+
#include "Framework/runDataProcessing.h"
18+
#include "Analysis/TrackSelection.h"
19+
#include "Analysis/TrackSelectionTables.h"
20+
#include "Analysis/trackUtilities.h"
21+
22+
using namespace o2;
23+
using namespace o2::framework;
24+
using namespace o2::framework::expressions;
25+
26+
//****************************************************************************************
27+
/**
28+
* Produce track filter table.
29+
*/
30+
//****************************************************************************************
31+
struct TrackSelectionTask {
32+
Produces<aod::TrackSelection> filterTable;
33+
34+
void init(InitContext&)
35+
{
36+
}
37+
38+
void process(soa::Join<aod::FullTracks, aod::TracksExtended> const& tracks)
39+
{
40+
for (auto& track : tracks) {
41+
filterTable(kTRUE,
42+
kTRUE);
43+
}
44+
}
45+
};
46+
47+
//****************************************************************************************
48+
/**
49+
* Workflow definition.
50+
*/
51+
//****************************************************************************************
52+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
53+
{
54+
WorkflowSpec workflow{adaptAnalysisTask<TrackSelectionTask>("track-selection")};
55+
return workflow;
56+
}

Analysis/Tasks/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ add_subdirectory(PWGHF)
1414
add_subdirectory(PWGJE)
1515
add_subdirectory(PWGLF)
1616
add_subdirectory(PWGUD)
17+
add_subdirectory(ALICE3)
1718

1819

20+
o2_add_dpl_workflow(trackextension
21+
SOURCES trackextension.cxx
22+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore
23+
COMPONENT_NAME Analysis)
24+
1925
o2_add_dpl_workflow(trackselection
2026
SOURCES trackselection.cxx
2127
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore

Analysis/Tasks/trackextension.cxx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
//
12+
// Task performing basic track selection.
13+
//
14+
15+
#include "Framework/AnalysisDataModel.h"
16+
#include "Framework/AnalysisTask.h"
17+
#include "Framework/runDataProcessing.h"
18+
#include "Analysis/TrackSelection.h"
19+
#include "Analysis/TrackSelectionTables.h"
20+
#include "Analysis/trackUtilities.h"
21+
22+
using namespace o2;
23+
using namespace o2::framework;
24+
using namespace o2::framework::expressions;
25+
26+
//****************************************************************************************
27+
/**
28+
* Produce the more complicated derived track quantities needed for track selection.
29+
* FIXME: we shall run this only if all other selections are passed to avoid
30+
* FIXME: computing overhead and errors in calculations
31+
*/
32+
//****************************************************************************************
33+
struct TrackExtensionTask {
34+
35+
Produces<aod::TracksExtended> extendedTrackQuantities;
36+
37+
void process(aod::Collision const& collision, aod::FullTracks const& tracks)
38+
{
39+
for (auto& track : tracks) {
40+
41+
std::array<float, 2> dca{1e10f, 1e10f};
42+
// FIXME: temporary solution to remove tracks that should not be there after conversion
43+
if (track.trackType() == o2::aod::track::TrackTypeEnum::Run2GlobalTrack && track.itsChi2NCl() != 0.f && track.tpcChi2NCl() != 0.f && std::abs(track.x()) < 10.f) {
44+
float magField = 5.0; // in kG (FIXME: get this from CCDB)
45+
auto trackPar = getTrackPar(track);
46+
trackPar.propagateParamToDCA({collision.posX(), collision.posY(), collision.posZ()}, magField, &dca);
47+
}
48+
extendedTrackQuantities(dca[0], dca[1]);
49+
50+
// TODO: add realtive pt resolution sigma(pt)/pt \approx pt * sigma(1/pt)
51+
// TODO: add geometrical length / fiducial volume
52+
}
53+
}
54+
};
55+
56+
//****************************************************************************************
57+
/**
58+
* Workflow definition.
59+
*/
60+
//****************************************************************************************
61+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
62+
{
63+
WorkflowSpec workflow{adaptAnalysisTask<TrackExtensionTask>("track-extension")};
64+
return workflow;
65+
}

Analysis/Tasks/trackqa.cxx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414

1515
#include "Framework/AnalysisDataModel.h"
1616
#include "Framework/AnalysisTask.h"
17-
#include "Analysis/MC.h"
1817
#include "Framework/HistogramRegistry.h"
19-
20-
#include <cmath>
21-
18+
#include "Analysis/MC.h"
2219
#include "Analysis/TrackSelectionTables.h"
20+
#include "Analysis/TrackSelection.h"
21+
#include "Analysis/TrackSelectionDefaults.h"
2322

2423
using namespace o2;
2524
using namespace o2::framework;
@@ -28,7 +27,8 @@ using namespace o2::framework::expressions;
2827
void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
2928
{
3029
std::vector<ConfigParamSpec> options{
31-
{"mc", VariantType::Bool, false, {"Add MC QA histograms."}}};
30+
{"mc", VariantType::Bool, false, {"Add MC QA histograms."}},
31+
{"add-cut-qa", VariantType::Int, 0, {"Add track cut QA histograms."}}};
3232
std::swap(workflowOptions, options);
3333
}
3434
#include "Framework/runDataProcessing.h"
@@ -144,6 +144,28 @@ struct TrackQATask {
144144
}
145145
};
146146

147+
struct TrackCutQATask {
148+
HistogramRegistry cuts{"Cuts", true, {}, OutputObjHandlingPolicy::QAObject};
149+
TrackSelection selectedTracks = getGlobalTrackSelection();
150+
static constexpr int ncuts = static_cast<int>(TrackSelection::TrackCuts::kNCuts);
151+
void init(InitContext&)
152+
{
153+
cuts.add("single_cut", ";Cut;Tracks", kTH1D, {{ncuts, 0, ncuts}});
154+
for (int i = 0; i < ncuts; i++) {
155+
cuts.get<TH1>("single_cut")->GetXaxis()->SetBinLabel(1 + i, TrackSelection::mCutNames[i].data());
156+
}
157+
}
158+
159+
void process(soa::Join<aod::FullTracks, aod::TracksExtended>::iterator const& track)
160+
{
161+
for (int i = 0; i < ncuts; i++) {
162+
if (selectedTracks.IsSelected(track, static_cast<TrackSelection::TrackCuts>(i))) {
163+
cuts.fill("single_cut", i);
164+
}
165+
}
166+
}
167+
};
168+
147169
//****************************************************************************************
148170
/**
149171
* QA task including MC truth info.
@@ -169,10 +191,14 @@ struct TrackQATaskMC {
169191
//****************************************************************************************
170192
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
171193
{
172-
bool isMC = cfgc.options().get<bool>("mc");
194+
const bool isMC = cfgc.options().get<bool>("mc");
195+
const int add_cut_qa = cfgc.options().get<int>("add-cut-qa");
173196

174197
WorkflowSpec workflow;
175198
workflow.push_back(adaptAnalysisTask<TrackQATask>("track-qa-histograms"));
199+
if (add_cut_qa) {
200+
workflow.push_back(adaptAnalysisTask<TrackCutQATask>("track-cut-qa-histograms"));
201+
}
176202
if (isMC) {
177203
workflow.push_back(adaptAnalysisTask<TrackQATaskMC>("track-qa-histograms-mc"));
178204
}

0 commit comments

Comments
 (0)