Skip to content

Commit 63624ac

Browse files
ArkaprabhaSaha001arkaprabhaalibuild
authored
[PWGLF] Add new task for nuclei analysis in light ions. (#13018)
Co-authored-by: arkaprabha <arkaprabha.saha@cern.ch> Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 4a9edeb commit 63624ac

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

PWGLF/Tasks/Nuspex/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ o2physics_add_dpl_workflow(nuclei-ebye
119119
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
120120
COMPONENT_NAME Analysis)
121121

122+
o2physics_add_dpl_workflow(anti-nuclei-hist
123+
SOURCES antinucleiTask.cxx
124+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
125+
COMPONENT_NAME Analysis)
126+
122127
o2physics_add_dpl_workflow(nuclei-toward-transv
123128
SOURCES nuclei_in_toward_transv_regions.cxx
124129
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file antinucleiTask.cxx
13+
/// \brief A task to analyse Anti-nuclei
14+
/// \author Arkaprabha Saha <arkaprabha.saha@cern.ch>
15+
16+
#include "Common/Core/PID/TPCPIDResponse.h"
17+
#include "Common/Core/TrackSelection.h"
18+
#include "Common/Core/TrackSelectionDefaults.h"
19+
#include "Common/DataModel/Centrality.h"
20+
#include "Common/DataModel/EventSelection.h"
21+
#include "Common/DataModel/PIDResponse.h"
22+
#include "Common/DataModel/TrackSelectionTables.h"
23+
24+
#include "DataFormatsTPC/BetheBlochAleph.h"
25+
#include "Framework/AnalysisDataModel.h"
26+
#include "Framework/AnalysisTask.h"
27+
#include "Framework/HistogramRegistry.h"
28+
#include "Framework/runDataProcessing.h"
29+
30+
#include <TParameter.h>
31+
32+
#include <cmath>
33+
#include <string>
34+
#include <vector>
35+
36+
using namespace o2;
37+
using namespace o2::framework;
38+
using CollisionWithEvSel = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs>;
39+
using TotalTracks = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::pidTOFDe>;
40+
41+
namespace
42+
{
43+
static const std::vector<std::string> particleName{"d"};
44+
static const double kBetheBlochDefault[6]{-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32};
45+
static const std::vector<std::string> betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"};
46+
static const float maxEtaCut = 0.8f;
47+
static const int minTpcCrossedRowsCut = 70;
48+
static const float maxVertexZCut = 10.f;
49+
} // namespace
50+
51+
struct antinucleiTask {
52+
// Histogram registry: for holding histograms
53+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
54+
55+
// Configurable track cuts
56+
Configurable<float> trackNclusTPCcut{"trackNclusTPCcut", 70.0f, "min number of TPC clusters"};
57+
Configurable<float> trackNclusITScut{"trackNclusITScut", 4.0f, "min number of ITS clusters"};
58+
Configurable<float> chi2TPC{"chi2TPC", 4.0f, "max chi2 per cluster TPC"};
59+
Configurable<float> chi2ITS{"chi2ITS", 36.0f, "max chi2 per cluster ITS"};
60+
Configurable<float> trackDCAz{"trackDCAz", 0.1f, "maxDCAz"};
61+
Configurable<float> trackDCAxy{"trackDCAxy", 0.1f, "maxDCAxy"};
62+
Configurable<float> tpcNSigmaCut{"tpcNSigmaCut", 3.0f, "tpcNSigmaCut"};
63+
Configurable<LabeledArray<double>> cfgBetheBlochParams{"cfgBetheBlochParams", {kBetheBlochDefault, 1, 6, particleName, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for deuteron"};
64+
65+
void init(InitContext const&)
66+
{ // Defining the Histogram Axes
67+
ConfigurableAxis etaAxis{"etaAxis", {16, -0.8, +0.8}, "#eta"};
68+
ConfigurableAxis phiAxis{"phiAxis", {70, 0.f, 7.f}, "#phi"};
69+
ConfigurableAxis zVtxAxis{"zVtxAxis", {100, -20.f, 20.f}, "Primary Vertex z (cm)"};
70+
ConfigurableAxis nSigmaAxis{"nSigmaAxis", {50, -5.f, 5.f}, "N_{#sigma}"};
71+
ConfigurableAxis ptAxis{"ptAxis", {100, -5.0f, 5.0f}, "p_{T} (GeV/c)"};
72+
ConfigurableAxis centAxis{"centAxis", {100, 0, 100.0f}, "Centrality"};
73+
ConfigurableAxis momAxis{"momAxis", {5.e2, 0.f, 5.f}, "momentum axis binning"};
74+
ConfigurableAxis tpcAxis{"tpcAxis", {4.e2, 0.f, 4.e3f}, "tpc signal axis binning"};
75+
76+
// Creating histograms
77+
histos.add("RawzVtx", "RawzVtx", kTH1F, {{zVtxAxis, "Primary Vertex z (cm)"}});
78+
histos.add("zVtx", "zVtx", kTH1F, {{zVtxAxis, "Primary Vertex z (cm)"}});
79+
histos.add("RawEta", "RawEta", kTH1F, {{etaAxis, "#eta"}});
80+
histos.add("Eta", "Eta", kTH1F, {{etaAxis, "#eta"}});
81+
histos.add("RawPhi", "RawPhi", kTH1F, {{phiAxis, "#phi (rad)"}});
82+
histos.add("Phi", "Phi", kTH1F, {{phiAxis, "#phi (rad)"}});
83+
histos.add("RawPt", "RawPt", kTH1F, {{ptAxis, "#it{p}_{T} (GeV/#it{c})"}});
84+
histos.add("Pt", "Pt", kTH1F, {{ptAxis, "#it{p}_{T} (GeV/#it{c})"}});
85+
histos.add("TpcSignal", "TpcSignal", kTH2F, {{momAxis, "#it{p}_{TPC} (GeV/#it{c})"}, {tpcAxis, "d#it{E}/d#it{x}_{TPC}"}});
86+
histos.add("RawtpcNSigma", "RawtpcNSigma", kTH3F, {{centAxis, "Centrality"}, {ptAxis, "#it{p}_{T} (GeV/#it{c})"}, {nSigmaAxis, "N_{#sigma}"}});
87+
histos.add("tpcNSigma", "tpcNSigma", kTH3F, {{centAxis, "Centrality"}, {ptAxis, "#it{p}_{T} (GeV/#it{c})"}, {nSigmaAxis, "N_{#sigma}"}});
88+
histos.add("RawtofNSigma", "RawtofNSigma", kTH3F, {{centAxis, "Centrality"}, {ptAxis, "#it{p}_{T} (GeV/#it{c})"}, {nSigmaAxis, "N_{#sigma}"}});
89+
histos.add("tofNSigma", "tofNSigma", kTH3F, {{centAxis, "Centrality"}, {ptAxis, "#it{p}_{T} (GeV/#it{c})"}, {nSigmaAxis, "N_{#sigma}"}});
90+
}
91+
92+
// Function to apply track cuts
93+
template <typename T>
94+
bool isGoodTrack(const T& track)
95+
{
96+
if (track.eta() > maxEtaCut)
97+
return false;
98+
if (track.tpcNClsFound() < trackNclusTPCcut)
99+
return false;
100+
if (track.tpcNClsCrossedRows() < minTpcCrossedRowsCut)
101+
return false;
102+
if (track.itsNCls() < trackNclusITScut)
103+
return false;
104+
if (track.tpcChi2NCl() > chi2TPC)
105+
return false;
106+
if (track.itsChi2NCl() > chi2ITS)
107+
return false;
108+
if (std::abs(track.dcaXY()) > trackDCAxy)
109+
return false;
110+
if (std::abs(track.dcaZ()) > trackDCAz)
111+
return false;
112+
113+
return true;
114+
}
115+
116+
// The process function
117+
void process(CollisionWithEvSel::iterator const& collision, TotalTracks const& tracks)
118+
{
119+
// Event Selection
120+
if (std::abs(collision.posZ()) > maxVertexZCut) {
121+
return;
122+
}
123+
124+
// Filling the z-vertex histogram before the event selection cuts.
125+
histos.fill(HIST("RawzVtx"), collision.posZ());
126+
127+
// Applying the built-in O2 event selection (sel8).
128+
if (!collision.sel8()) {
129+
return;
130+
}
131+
132+
// Filling the z-vertex histogram after the event selection cuts.
133+
histos.fill(HIST("zVtx"), collision.posZ());
134+
135+
// Track Selection
136+
for (const auto& track : tracks) {
137+
138+
double expBethe{tpc::BetheBlochAleph(static_cast<double>(track.tpcInnerParam() / o2::constants::physics::MassDeuteron), cfgBetheBlochParams->get("p0"), cfgBetheBlochParams->get("p1"), cfgBetheBlochParams->get("p2"), cfgBetheBlochParams->get("p3"), cfgBetheBlochParams->get("p4"))};
139+
double expSigma{expBethe * cfgBetheBlochParams->get("resolution")};
140+
float tpcNSigmaDeuteron = static_cast<float>((track.tpcSignal() - expBethe) / expSigma);
141+
142+
float pt = track.sign() > 0 ? track.pt() : -track.pt();
143+
// Filling histograms with track data before applying any cuts.
144+
histos.fill(HIST("RawEta"), track.eta());
145+
histos.fill(HIST("RawPhi"), track.phi());
146+
histos.fill(HIST("RawPt"), pt);
147+
histos.fill(HIST("RawtpcNSigma"), collision.centFT0C(), pt, tpcNSigmaDeuteron);
148+
histos.fill(HIST("RawtofNSigma"), collision.centFT0C(), pt, track.tofNSigmaDe());
149+
150+
// If the track is good, fill the "after cuts" histograms.
151+
if (isGoodTrack(track)) {
152+
histos.fill(HIST("Eta"), track.eta());
153+
histos.fill(HIST("Phi"), track.phi());
154+
histos.fill(HIST("Pt"), pt);
155+
histos.fill(HIST("tpcNSigma"), collision.centFT0C(), pt, tpcNSigmaDeuteron);
156+
histos.fill(HIST("TpcSignal"), track.tpcInnerParam(), track.tpcSignal());
157+
158+
if (std::abs(tpcNSigmaDeuteron) < tpcNSigmaCut) {
159+
histos.fill(HIST("tofNSigma"), collision.centFT0C(), pt, track.tofNSigmaDe());
160+
}
161+
}
162+
}
163+
}
164+
165+
PROCESS_SWITCH(antinucleiTask, process, "process", true);
166+
};
167+
168+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
169+
{
170+
return WorkflowSpec{
171+
adaptAnalysisTask<antinucleiTask>(cfgc)};
172+
}

0 commit comments

Comments
 (0)