Skip to content

Commit 2c3a7e7

Browse files
authored
[PWGCF] add generic pair tasks (#13096)
1 parent bd636ac commit 2c3a7e7

24 files changed

+1694
-174
lines changed

PWGCF/Femto/Core/baseSelection.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class BaseSelection
6363
if (static_cast<size_t>(observableIndex) >= NumObservables) {
6464
LOG(fatal) << "Observable is not valid. Observable (index) has to be smaller than " << NumObservables;
6565
}
66-
if (skipMostPermissiveBit) {
66+
if (!selectionValues.empty() && skipMostPermissiveBit) {
6767
mNSelections += selectionValues.size() - 1;
6868
} else {
6969
mNSelections += selectionValues.size();
@@ -115,9 +115,6 @@ class BaseSelection
115115
/// \param observableIndex Index of the observable.
116116
void addSelection(int mode, int observableIndex)
117117
{
118-
if (static_cast<size_t>(observableIndex) >= NumObservables) {
119-
LOG(fatal) << "Observable is not valid. Observable (index) has to be smaller than " << NumObservables;
120-
}
121118
switch (mode) {
122119
case -1: // cut is optional and we store bit for the cut
123120
mNSelections += 1;
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
// Copyright 2019-2022 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 closePairRejection.h
13+
/// \brief Definition of ClosePairRejection class
14+
/// \author Anton Riedel, TU München, anton.riedel@tum.de
15+
16+
#ifndef PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_
17+
#define PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_
18+
19+
#include "PWGCF/Femto/Core/femtoUtils.h"
20+
#include "PWGCF/Femto/Core/histManager.h"
21+
22+
#include "Framework/HistogramRegistry.h"
23+
24+
#include <array>
25+
#include <map>
26+
#include <numeric>
27+
#include <string>
28+
#include <vector>
29+
30+
namespace o2::analysis::femto
31+
{
32+
namespace closepairrejection
33+
{
34+
// enum for track histograms
35+
enum CprHist {
36+
// kinemtics
37+
kAverage,
38+
kRadius0,
39+
kRadius1,
40+
kRadius2,
41+
kRadius3,
42+
kRadius4,
43+
kRadius5,
44+
kRadius6,
45+
kRadius7,
46+
kRadius8,
47+
kCprHistogramLast
48+
};
49+
50+
struct ConfCpr : o2::framework::ConfigurableGroup {
51+
std::string prefix = std::string("ClosePairRejection");
52+
o2::framework::Configurable<bool> on{"on", true, "Turn on CPR"};
53+
o2::framework::Configurable<float> detaMax{"detaMax", 0.01f, "Maximium deta"};
54+
o2::framework::Configurable<float> dphistarMax{"dphistarMax", 0.01f, "Maximum dphistar"};
55+
o2::framework::ConfigurableAxis binningDeta{"binningDeta", {{500, -0.5, 0.5}}, "deta"};
56+
o2::framework::ConfigurableAxis binningDphistar{"binningDphistar", {{500, -0.5, 0.5}}, "dphi"};
57+
};
58+
59+
// tpc radii for computing phistar
60+
constexpr int kNradii = 9;
61+
constexpr std::array<float, kNradii> kTpcRadius = {85., 105., 125., 145., 165., 185., 205., 225., 245.};
62+
63+
// directory names
64+
constexpr char PrefixTrackTrackSe[] = "CPR_TrackTrack/SE/";
65+
constexpr char PrefixTrackTrackMe[] = "CPR_TrackTrack/ME/";
66+
constexpr char PrefixTrackV0Se[] = "CPR_TrackV0/SE/";
67+
constexpr char PrefixTrackV0Me[] = "CPR_TrackV0/ME/";
68+
69+
// must be in sync with enum TrackVariables
70+
// the enum gives the correct index in the array
71+
constexpr std::array<histmanager::HistInfo<CprHist>, kCprHistogramLast> HistTable = {
72+
{{kAverage, o2::framework::kTH2F, "hAverage", "#Delta #eta vs #Delta #phi* (averaged over all radii); #Delta #eta; #Delta #phi*"},
73+
{kRadius0, o2::framework::kTH2F, "hRadius0", "Radius 0: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
74+
{kRadius1, o2::framework::kTH2F, "hRadius1", "Radius 1: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
75+
{kRadius2, o2::framework::kTH2F, "hRadius2", "Radius 2: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
76+
{kRadius3, o2::framework::kTH2F, "hRadius3", "Radius 3: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
77+
{kRadius4, o2::framework::kTH2F, "hRadius4", "Radius 4: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
78+
{kRadius5, o2::framework::kTH2F, "hRadius5", "Radius 5: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
79+
{kRadius6, o2::framework::kTH2F, "hRadius6", "Radius 6: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
80+
{kRadius7, o2::framework::kTH2F, "hRadius7", "Radius 7: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"},
81+
{kRadius8, o2::framework::kTH2F, "hRadius8", "Radius 8: #Delta #eta vs #Delta #phi*; #Delta #eta; #Delta #phi*"}}};
82+
83+
template <typename T>
84+
auto makeCprHistSpecMap(const T& confCpr)
85+
{
86+
return std::map<CprHist, std::vector<framework::AxisSpec>>{
87+
{kAverage, {confCpr.binningDeta, confCpr.binningDphistar}},
88+
{kRadius0, {confCpr.binningDeta, confCpr.binningDphistar}},
89+
{kRadius1, {confCpr.binningDeta, confCpr.binningDphistar}},
90+
{kRadius2, {confCpr.binningDeta, confCpr.binningDphistar}},
91+
{kRadius3, {confCpr.binningDeta, confCpr.binningDphistar}},
92+
{kRadius4, {confCpr.binningDeta, confCpr.binningDphistar}},
93+
{kRadius5, {confCpr.binningDeta, confCpr.binningDphistar}},
94+
{kRadius6, {confCpr.binningDeta, confCpr.binningDphistar}},
95+
{kRadius7, {confCpr.binningDeta, confCpr.binningDphistar}},
96+
{kRadius8, {confCpr.binningDeta, confCpr.binningDphistar}}};
97+
};
98+
99+
template <const char* prefix>
100+
class CloseTrackRejection
101+
{
102+
public:
103+
CloseTrackRejection() = default;
104+
virtual ~CloseTrackRejection() = default;
105+
106+
void init(o2::framework::HistogramRegistry* registry, std::map<CprHist, std::vector<o2::framework::AxisSpec>>& specs, float detaMax, float dphistarMax, int chargeTrack1, int chargeTrack2)
107+
{
108+
mDetaMax = detaMax;
109+
mDphistarMax = dphistarMax;
110+
111+
if (mDetaMax < o2::constants::math::Epsilon || mDphistarMax < o2::constants::math::Epsilon) {
112+
LOG(fatal) << "Either DetaMax or DphistarMax are 0 or negative. Either turn off CPR or specify reasonable values. Breaking ...";
113+
}
114+
mChargeTrack1 = chargeTrack1;
115+
mChargeTrack2 = chargeTrack2;
116+
117+
if (utils::sign(mChargeTrack1) != utils::sign(mChargeTrack2)) {
118+
LOG(warn) << "CPR is truned on for tracks with opposite charge. Is this intended?";
119+
}
120+
121+
mHistogramRegistry = registry;
122+
123+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kAverage, HistTable), GetHistDesc(kAverage, HistTable), GetHistType(kAverage, HistTable), {specs.at(kAverage)});
124+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius0, HistTable), GetHistDesc(kRadius0, HistTable), GetHistType(kRadius0, HistTable), {specs.at(kRadius0)});
125+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius1, HistTable), GetHistDesc(kRadius1, HistTable), GetHistType(kRadius1, HistTable), {specs.at(kRadius1)});
126+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius2, HistTable), GetHistDesc(kRadius2, HistTable), GetHistType(kRadius2, HistTable), {specs.at(kRadius2)});
127+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius3, HistTable), GetHistDesc(kRadius3, HistTable), GetHistType(kRadius3, HistTable), {specs.at(kRadius3)});
128+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius4, HistTable), GetHistDesc(kRadius4, HistTable), GetHistType(kRadius4, HistTable), {specs.at(kRadius4)});
129+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius5, HistTable), GetHistDesc(kRadius5, HistTable), GetHistType(kRadius5, HistTable), {specs.at(kRadius5)});
130+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius6, HistTable), GetHistDesc(kRadius6, HistTable), GetHistType(kRadius6, HistTable), {specs.at(kRadius6)});
131+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius7, HistTable), GetHistDesc(kRadius7, HistTable), GetHistType(kRadius7, HistTable), {specs.at(kRadius7)});
132+
mHistogramRegistry->add(std::string(prefix) + GetHistNamev2(kRadius8, HistTable), GetHistDesc(kRadius8, HistTable), GetHistType(kRadius8, HistTable), {specs.at(kRadius8)});
133+
}
134+
135+
void setMagField(float magField) { mMagField = magField; }
136+
137+
template <typename T1, typename T2>
138+
void compute(const T1& track1, const T2& track2)
139+
{
140+
// reset values
141+
mAverageDphistar = 0.f;
142+
mDeta = 0.f;
143+
mDphistar.fill(0.f);
144+
145+
mDeta = track1.eta() - track2.eta();
146+
for (size_t i = 0; i < kTpcRadius.size(); i++) {
147+
auto phistar1 = utils::dphistar(mMagField, kTpcRadius[i], mChargeTrack1, track1.pt(), track1.phi());
148+
auto phistar2 = utils::dphistar(mMagField, kTpcRadius[i], mChargeTrack2, track2.pt(), track2.phi());
149+
if (phistar1 && phistar2) {
150+
// if the calculation for one phistar fails, keep the default value, which is 0
151+
// this makes it more likelier for the pair to be rejected sind the averave will be biased towards lower values
152+
mDphistar.at(i) = phistar1.value() - phistar2.value();
153+
}
154+
}
155+
mAverageDphistar = std::accumulate(mDphistar.begin(), mDphistar.end(), 0.f) / mDphistar.size();
156+
}
157+
158+
void fill()
159+
{
160+
// fill average hist
161+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kAverage, HistTable)), mDeta, mAverageDphistar);
162+
163+
// fill radii hists
164+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius0, HistTable)), mDeta, mDphistar.at(0));
165+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius1, HistTable)), mDeta, mDphistar.at(1));
166+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius2, HistTable)), mDeta, mDphistar.at(2));
167+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius3, HistTable)), mDeta, mDphistar.at(3));
168+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius4, HistTable)), mDeta, mDphistar.at(4));
169+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius5, HistTable)), mDeta, mDphistar.at(5));
170+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius6, HistTable)), mDeta, mDphistar.at(6));
171+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius7, HistTable)), mDeta, mDphistar.at(7));
172+
mHistogramRegistry->fill(HIST(prefix) + HIST(GetHistName(kRadius8, HistTable)), mDeta, mDphistar.at(8));
173+
}
174+
175+
bool isClosePair() const
176+
{
177+
return std::hypot(mAverageDphistar / mDphistarMax, mDeta / mDetaMax) < 1.f;
178+
}
179+
180+
private:
181+
int mChargeTrack1 = 0;
182+
int mChargeTrack2 = 0;
183+
float mMagField = 0.f;
184+
float mAverageDphistar = 0.f;
185+
float mDeta = 0.f;
186+
float mDetaMax = 0.f;
187+
float mDphistarMax = 0.f;
188+
std::array<float, kNradii> mDphistar = {0.f};
189+
190+
o2::framework::HistogramRegistry* mHistogramRegistry = nullptr;
191+
};
192+
193+
template <const char* prefix>
194+
class ClosePairRejectionTrackTrack
195+
{
196+
public:
197+
void init(o2::framework::HistogramRegistry* registry, std::map<CprHist, std::vector<o2::framework::AxisSpec>>& specs, float detaMax, float dphistarMax, int signTrack1, int absChargeTrack1, int signTrack2, int AbsChargeTrack2, bool isActivated)
198+
{
199+
mIsActivated = isActivated;
200+
mCtr.init(registry, specs, detaMax, dphistarMax, signTrack1 * absChargeTrack1, signTrack2 * AbsChargeTrack2);
201+
}
202+
203+
void setMagField(float magField) { mCtr.setMagField(magField); }
204+
template <typename T1, typename T2>
205+
void setPair(const T1& track1, const T2& track2)
206+
{
207+
mCtr.compute(track1, track2);
208+
}
209+
bool isClosePair() const { return mCtr.isClosePair(); }
210+
void fill() { mCtr.fill(); }
211+
bool isActivated() const { return mIsActivated; }
212+
213+
private:
214+
CloseTrackRejection<prefix> mCtr;
215+
bool mIsActivated = true;
216+
};
217+
218+
template <const char* prefix>
219+
class ClosePairRejectionTrackV0 // can also be used for any particle type that has pos/neg daughters, like resonances
220+
{
221+
public:
222+
void init(o2::framework::HistogramRegistry* registry, std::map<CprHist, std::vector<o2::framework::AxisSpec>>& specs, float detaMax, float dphistarMax, int signTrack, int absChargeTrack, bool isActivated)
223+
{
224+
mIsActivated = isActivated;
225+
mSignTrack = signTrack;
226+
227+
// initialize CPR with charge of the track and the same charge for the daughter particle
228+
// absolute charge of the daughter track will be 1, so we can pass the sign directly
229+
mCtr.init(registry, specs, detaMax, dphistarMax, signTrack * absChargeTrack, signTrack);
230+
}
231+
232+
void setMagField(float magField)
233+
{
234+
mCtr.setMagField(magField);
235+
}
236+
template <typename T1, typename T2, typename T3>
237+
void setPair(const T1& track, const T2& v0, const T3 /*trackTable*/)
238+
{
239+
if (mSignTrack == 1) {
240+
auto daughter = v0.template posDau_as<T3>();
241+
mCtr.compute(track, daughter);
242+
} else if (mSignTrack == -1) {
243+
auto daughter = v0.template negDau_as<T3>();
244+
mCtr.compute(track, daughter);
245+
} else {
246+
LOG(fatal) << "CPR Track-V0: Wrong track sign";
247+
}
248+
}
249+
250+
bool isClosePair() const { return mCtr.isClosePair(); }
251+
void fill()
252+
{
253+
mCtr.fill();
254+
}
255+
bool isActivated() const { return mIsActivated; }
256+
257+
private:
258+
CloseTrackRejection<prefix> mCtr;
259+
int mSignTrack = 0;
260+
bool mIsActivated = true;
261+
};
262+
263+
}; // namespace closepairrejection
264+
}; // namespace o2::analysis::femto
265+
#endif // PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_

0 commit comments

Comments
 (0)