Skip to content

Commit 3dc71cc

Browse files
authored
LF task: v0 and cascade absorption (#3515)
* task: v0 and cascade absorption
1 parent d405ff9 commit 3dc71cc

2 files changed

Lines changed: 339 additions & 0 deletions

File tree

PWGLF/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ o2physics_add_dpl_workflow(hypertriton3bodymcqa
191191
PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore
192192
COMPONENT_NAME Analysis)
193193

194+
o2physics_add_dpl_workflow(vzero-cascade-absorption
195+
SOURCES vzero_cascade_absorption.cxx
196+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
197+
COMPONENT_NAME Analysis)
198+
194199
o2physics_add_dpl_workflow(vertexqa
195200
SOURCES vertexQA.cxx
196201
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
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+
/// \author Alberto Caliva (alberto.caliva@cern.ch)
13+
/// \since September 26, 2023
14+
15+
#include "Framework/runDataProcessing.h"
16+
#include "Framework/AnalysisTask.h"
17+
#include "Framework/AnalysisDataModel.h"
18+
#include "Framework/ASoAHelpers.h"
19+
#include "ReconstructionDataFormats/Track.h"
20+
#include "Common/Core/RecoDecay.h"
21+
#include "Common/Core/trackUtilities.h"
22+
#include "PWGLF/DataModel/LFStrangenessTables.h"
23+
#include "Common/Core/TrackSelection.h"
24+
#include "Common/DataModel/TrackSelectionTables.h"
25+
#include "Common/DataModel/EventSelection.h"
26+
#include "Common/DataModel/Centrality.h"
27+
#include "Common/DataModel/PIDResponse.h"
28+
29+
using namespace o2;
30+
using namespace o2::framework;
31+
using namespace o2::framework::expressions;
32+
using std::array;
33+
34+
using SelectedCollisions = soa::Join<aod::Collisions, aod::EvSels>;
35+
36+
using FullTracks = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksCov, aod::TracksIU, aod::TracksCovIU, aod::TracksDCA, aod::pidTOFbeta, aod::pidTOFmass, aod::TrackSelection, aod::TrackSelectionExtension, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>;
37+
using FullTrack = FullTracks::iterator;
38+
39+
struct vzero_cascade_absorption {
40+
41+
// QC Histograms
42+
HistogramRegistry registryQC{
43+
"registryQC",
44+
{},
45+
OutputObjHandlingPolicy::AnalysisObject,
46+
true,
47+
true};
48+
49+
// Analysis Histograms: Data
50+
HistogramRegistry registryData{
51+
"registryData",
52+
{},
53+
OutputObjHandlingPolicy::AnalysisObject,
54+
true,
55+
true};
56+
57+
// Analysis Histograms: MC
58+
HistogramRegistry registryMC{
59+
"registryMC",
60+
{},
61+
OutputObjHandlingPolicy::AnalysisObject,
62+
true,
63+
true};
64+
65+
// Configurable Parameters
66+
Configurable<float> minTPCnClsFound{"minTPCnClsFound", 80.0f, "min number of found TPC clusters"};
67+
Configurable<float> minNCrossedRowsTPC{"minNCrossedRowsTPC", 80.0f, "min number of found TPC crossed rows"};
68+
Configurable<float> maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"};
69+
Configurable<float> etaMin{"etaMin", -0.5f, "etaMin"};
70+
Configurable<float> etaMax{"etaMax", +0.5f, "etaMax"};
71+
Configurable<float> pMin_k0postrack{"pMin_k0postrack", 0.3f, "Min Momentum K0 pos track"};
72+
Configurable<float> pMax_k0postrack{"pMax_k0postrack", 5.0f, "Max Momentum K0 pos track"};
73+
Configurable<float> pMin_k0negtrack{"pMin_k0negtrack", 0.3f, "Min Momentum K0 neg track"};
74+
Configurable<float> pMax_k0negtrack{"pMax_k0negtrack", 5.0f, "Max Momentum K0 neg track"};
75+
Configurable<bool> requireITShits{"requireITShits", true, "require ITS hits for daughters"};
76+
Configurable<std::vector<float>> hit_requirement_before_target{"hit_requirement_before_target", {0, 0, 0, 1, 1, 1, 1}, "ITS Hits before target"};
77+
Configurable<std::vector<float>> hit_requirement_after_target{"hit_requirement_after_target", {0, 0, 0, 0, 0, 1, 1}, "ITS Hits after target"};
78+
Configurable<bool> useTOF{"useTOF", true, "use TOF for PID"};
79+
Configurable<float> nsigmaTPCmin{"nsigmaTPCmin", -3.0f, "Minimum nsigma TPC"};
80+
Configurable<float> nsigmaTPCmax{"nsigmaTPCmax", +3.0f, "Maximum nsigma TPC"};
81+
Configurable<float> nsigmaTOFmin{"nsigmaTOFmin", -3.0f, "Minimum nsigma TOF"};
82+
Configurable<float> nsigmaTOFmax{"nsigmaTOFmax", +3.0f, "Maximum nsigma TOF"};
83+
Configurable<float> minimumV0Radius{"minimumV0Radius", 0.5f, "Minimum V0 Radius"};
84+
Configurable<float> maximumV0Radius{"maximumV0Radius", 40.0f, "Maximum V0 Radius"};
85+
Configurable<float> minimumCascRadius{"minimumCascRadius", 0.5f, "Minimum Cascade Radius"};
86+
Configurable<float> maximumCascRadius{"maximumCascRadius", 40.0f, "Maximum Cascade Radius"};
87+
Configurable<float> dcanegtoPVmin{"dcanegtoPVmin", 0.1f, "Minimum DCA Neg To PV"};
88+
Configurable<float> dcapostoPVmin{"dcapostoPVmin", 0.1f, "Minimum DCA Pos To PV"};
89+
Configurable<float> dcaBachelorToPVmin{"dcaBachelorToPVmin", 0.1f, "Minimum DCA bachelor To PV"};
90+
Configurable<float> dcaV0ToPVmin{"dcaV0ToPVmin", 0.1f, "Minimum DCA V0 To PV for cascades"};
91+
Configurable<float> v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"};
92+
Configurable<float> casccospaMin{"casccospaMin", 0.998f, "Minimum Cascade CosPA"};
93+
Configurable<float> dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, "Maximum DCA Daughters"};
94+
Configurable<float> dcaCascDaughtersMax{"dcaCascDaughtersMax", 0.5f, "Maximum DCA Cascade Daughters"};
95+
Configurable<float> Rmin_beforeAbs{"Rmin_beforeAbs", 10.0f, "Rmin before target"};
96+
Configurable<float> Rmax_beforeAbs{"Rmax_beforeAbs", 15.0f, "Rmax before target"};
97+
Configurable<float> Rmin_afterAbs{"Rmin_afterAbs", 26.0f, "Rmin after target"};
98+
Configurable<float> Rmax_afterAbs{"Rmax_afterAbs", 31.0f, "Rmax after target"};
99+
100+
void init(InitContext const&)
101+
{
102+
// Histograms
103+
registryQC.add("event_counter", "event counter", HistType::kTH1F, {{2, 0, 2, "number of events"}});
104+
registryData.add("K0_before_target", "K0 before target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {240, 0.44, 0.56, "m (GeV/c^{2})"}});
105+
registryData.add("K0_after_target", "K0 after target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {240, 0.44, 0.56, "m (GeV/c^{2})"}});
106+
107+
/*
108+
registryData.add("Lambda_before_target", "Lambda_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.09, 1.14, "m (GeV/c)"}});
109+
registryData.add("Lambda_after_target", "Lambda_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.09, 1.14, "m (GeV/c)"}});
110+
registryData.add("AntiLambda_before_target", "AntiLambda_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.09, 1.14, "m (GeV/c)"}});
111+
registryData.add("AntiLambda_after_target", "AntiLambda_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.09, 1.14, "m (GeV/c)"}});
112+
registryData.add("Csi_before_target", "Csi_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.305, 1.34, "m (GeV/c)"}});
113+
registryData.add("Csi_after_target", "Csi_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.305, 1.34, "m (GeV/c)"}});
114+
registryData.add("AntiCsi_before_target", "AntiCsi_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.3, 1.35, "m (GeV/c)"}});
115+
registryData.add("AntiCsi_after_target", "AntiCsi_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.3, 1.35, "m (GeV/c)"}});
116+
registryData.add("Omega_before_target", "Omega_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.6, 1.75, "m (GeV/c)"}});
117+
registryData.add("Omega_after_target", "Omega_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.6, 1.75, "m (GeV/c)"}});
118+
registryData.add("AntiOmega_before_target", "AntiOmega_before_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.6, 1.75, "m (GeV/c)"}});
119+
registryData.add("AntiOmega_after_target", "AntiOmega_after_target", HistType::kTH2F, {{200, 0.0, 10.0, "p (GeV/c)"}, {200, 1.6, 1.75, "m (GeV/c)"}});*/
120+
}
121+
122+
bool hasHitOnITSlayer(uint8_t itsClsmap, int layer)
123+
{
124+
125+
unsigned char test_bit = 1 << layer;
126+
return (itsClsmap & test_bit);
127+
}
128+
129+
// Single-Track Selection
130+
template <typename T1, typename C>
131+
bool passedSingleTrackSelection(const T1& track, const C& collision)
132+
{
133+
// Single-Track Selections
134+
if (!track.hasITS())
135+
return false;
136+
if (!track.hasTPC())
137+
return false;
138+
if (!track.passedTPCRefit())
139+
return false;
140+
if (track.tpcNClsFound() < minTPCnClsFound)
141+
return false;
142+
if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC)
143+
return false;
144+
if (track.tpcChi2NCl() > maxChi2TPC)
145+
return false;
146+
if (track.eta() < etaMin || track.eta() > etaMax)
147+
return false;
148+
if (useTOF && (!track.hasTOF()))
149+
return false;
150+
return true;
151+
}
152+
153+
// K0s Selections
154+
template <typename T1, typename T2, typename C>
155+
bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack,
156+
const C& collision)
157+
{
158+
// Single-Track Selections
159+
if (!passedSingleTrackSelection(ptrack, collision))
160+
return false;
161+
if (!passedSingleTrackSelection(ntrack, collision))
162+
return false;
163+
164+
// Momentum K0 Daughters
165+
float p_k0postrack = TMath::Sqrt(v0.pxpos() * v0.pxpos() + v0.pypos() * v0.pypos() + v0.pzpos() * v0.pzpos());
166+
float p_k0negtrack = TMath::Sqrt(v0.pxneg() * v0.pxneg() + v0.pyneg() * v0.pyneg() + v0.pzneg() * v0.pzneg());
167+
168+
// Momentum Interval
169+
if (p_k0postrack < pMin_k0postrack || p_k0postrack > pMax_k0postrack)
170+
return false;
171+
if (p_k0negtrack < pMin_k0negtrack || p_k0negtrack > pMax_k0negtrack)
172+
return false;
173+
174+
// V0 Selections
175+
if (v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < v0cospaMin)
176+
return false;
177+
if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius)
178+
return false;
179+
if (v0.dcaV0daughters() > dcaV0DaughtersMax)
180+
return false;
181+
if (v0.dcapostopv() < dcapostoPVmin)
182+
return false;
183+
if (v0.dcanegtopv() < dcanegtoPVmin)
184+
return false;
185+
186+
// PID Selections (TPC)
187+
if (ptrack.tpcNSigmaPi() < nsigmaTPCmin || ptrack.tpcNSigmaPi() > nsigmaTPCmax)
188+
return false;
189+
if (ntrack.tpcNSigmaPi() < nsigmaTPCmin || ntrack.tpcNSigmaPi() > nsigmaTPCmax)
190+
return false;
191+
192+
// PID Selections (TOF)
193+
if (useTOF) {
194+
if (ptrack.tofNSigmaPi() < nsigmaTOFmin || ptrack.tofNSigmaPi() > nsigmaTOFmax)
195+
return false;
196+
if (ntrack.tofNSigmaPi() < nsigmaTOFmin || ntrack.tofNSigmaPi() > nsigmaTOFmax)
197+
return false;
198+
}
199+
200+
return true;
201+
}
202+
203+
/*
204+
// Lambda Selections
205+
template <typename T1, typename T2, typename C>
206+
bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack,
207+
const C& collision)
208+
{
209+
// Single-Track Selections
210+
if (!passedSingleTrackSelection(ptrack, collision))
211+
return false;
212+
if (!passedSingleTrackSelection(ntrack, collision))
213+
return false;
214+
215+
if (ptrack.tpcInnerParam() > 0.6) {
216+
if (!ptrack.hasTOF())
217+
return false;
218+
if (TMath::Abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax)
219+
return false;
220+
}
221+
222+
if (ntrack.tpcInnerParam() > 0.6) {
223+
if (!ntrack.hasTOF())
224+
return false;
225+
if (TMath::Abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax)
226+
return false;
227+
}
228+
229+
// Invariant-Mass Selection
230+
if (v0.mLambda() < minMassLambda || v0.mLambda() > maxMassLambda)
231+
return false;
232+
233+
return true;
234+
}
235+
236+
// AntiLambda Selections
237+
template <typename T1, typename T2, typename C>
238+
bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack,
239+
const T2& ptrack, const C& collision)
240+
{
241+
242+
// Single-Track Selections
243+
if (!passedSingleTrackSelection(ptrack, collision))
244+
return false;
245+
if (!passedSingleTrackSelection(ntrack, collision))
246+
return false;
247+
248+
if (ptrack.tpcInnerParam() > 0.6) {
249+
if (!ptrack.hasTOF())
250+
return false;
251+
if (TMath::Abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax)
252+
return false;
253+
}
254+
255+
if (ntrack.tpcInnerParam() > 0.6) {
256+
if (!ntrack.hasTOF())
257+
return false;
258+
if (TMath::Abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax)
259+
return false;
260+
}
261+
262+
// Invariant-Mass Selection
263+
if (v0.mAntiLambda() < minMassLambda || v0.mAntiLambda() > maxMassLambda)
264+
return false;
265+
266+
return true;
267+
}
268+
*/
269+
270+
// Process Data
271+
void processData(SelectedCollisions::iterator const& collision,
272+
aod::V0Datas const& fullV0s, FullTracks const& tracks)
273+
{
274+
275+
// Event Counter (before event sel)
276+
registryQC.fill(HIST("event_counter"), 0.5);
277+
278+
// Event Selection
279+
if (!collision.sel8())
280+
return;
281+
282+
// Event Counter (after event sel)
283+
registryQC.fill(HIST("event_counter"), 1.5);
284+
285+
// Loop over Reconstructed V0s
286+
for (auto& v0 : fullV0s) {
287+
288+
// Positive and Negative Tracks
289+
const auto& posTrack = v0.posTrack_as<FullTracks>();
290+
const auto& negTrack = v0.negTrack_as<FullTracks>();
291+
292+
auto hit_before_target = static_cast<std::vector<float>>(hit_requirement_before_target);
293+
auto hit_after_target = static_cast<std::vector<float>>(hit_requirement_after_target);
294+
295+
// K0 Short
296+
if (passedK0Selection(v0, negTrack, posTrack, collision)) {
297+
298+
// Before Target
299+
if (v0.v0radius() > Rmin_beforeAbs && v0.v0radius() < Rmax_beforeAbs) {
300+
if (requireITShits) {
301+
for (int i = 0; i < 7; i++) {
302+
if (hit_before_target[i] > 0 && !hasHitOnITSlayer(posTrack.itsClusterMap(), i))
303+
continue;
304+
if (hit_before_target[i] > 0 && !hasHitOnITSlayer(negTrack.itsClusterMap(), i))
305+
continue;
306+
}
307+
}
308+
309+
registryData.fill(HIST("K0_before_target"), v0.p(), v0.mK0Short());
310+
}
311+
312+
// After Target
313+
if (v0.v0radius() > Rmin_afterAbs && v0.v0radius() < Rmax_afterAbs) {
314+
315+
if (requireITShits) {
316+
for (int i = 0; i < 7; i++) {
317+
if (hit_after_target[i] > 0 && !hasHitOnITSlayer(posTrack.itsClusterMap(), i))
318+
continue;
319+
if (hit_after_target[i] > 0 && !hasHitOnITSlayer(negTrack.itsClusterMap(), i))
320+
continue;
321+
}
322+
}
323+
324+
registryData.fill(HIST("K0_after_target"), v0.p(), v0.mK0Short());
325+
}
326+
}
327+
} // end loop on V0s
328+
}
329+
};
330+
331+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
332+
{
333+
return WorkflowSpec{adaptAnalysisTask<vzero_cascade_absorption>(cfgc)};
334+
}

0 commit comments

Comments
 (0)