Skip to content

Commit b759e13

Browse files
[PWGCF] Add multiplicity estimator task with pair trigger to femto framework (#17963)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent bfd04be commit b759e13

20 files changed

Lines changed: 2106 additions & 314 deletions

‎PWGCF/Femto/Core/baseSelection.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,15 @@ class BaseSelection
161161
/// -1 = optional cut, bit is stored in bitmask;
162162
/// 0 = cut is disabled, no bit stored;
163163
/// 1 = minimal (mandatory) cut, no extra bit stored since only one threshold exists.
164+
/// In pass-through mode, enabled selections (-1, 1) are stored as bits without being required,
165+
/// disabled selections (0) stay disabled so they do not occupy bits.
164166
void addSelection(int observableIndex,
165167
std::string const& selectionName,
166168
int mode)
167169
{
168170
int selectionMode = mode;
169171

170-
if (mPassThrough) {
172+
if (mPassThrough && mode != 0) {
171173
selectionMode = 2;
172174
}
173175
switch (selectionMode) {

‎PWGCF/Femto/Core/closePairRejection.h‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ enum CprHist {
6060
};
6161

6262
// template configurable group for Cpr
63-
template <auto& Prefix>
63+
// DefaultCutAverage: default of cutAverage (e.g. false for pairs of generated particles, where no detector effects are present)
64+
template <auto& Prefix, bool DefaultCutAverage = true>
6465
struct ConfCpr : o2::framework::ConfigurableGroup {
6566
std::string prefix = std::string(Prefix);
66-
o2::framework::Configurable<bool> cutAverage{"cutAverage", true, "Apply CPR if the average deta-dphistar is below the configured values"};
67+
o2::framework::Configurable<bool> cutAverage{"cutAverage", DefaultCutAverage, "Apply CPR if the average deta-dphistar is below the configured values"};
6768
o2::framework::Configurable<bool> cutAnyRadius{"cutAnyRadius", false, "Apply CPR if the deta-dphistar is below the configured values at any radius"};
6869
o2::framework::Configurable<bool> cutElipsoidal{"cutElipsoidal", true, "If true, apply CPR as episoidal cut. If false use rectangluar cut."};
6970
o2::framework::Configurable<bool> plotAllRadii{"plotAllRadii", true, "Plot deta-dphi distribution at all radii"};
@@ -100,6 +101,7 @@ constexpr const char PrefixCprV0DaughterV0DaughterNeg[] = "CprV0DaughterV0Daught
100101
constexpr const char PrefixCprV0DaughterResoDaughterPos[] = "CprV0DaughterResoDaughterPos";
101102
constexpr const char PrefixCprV0DaughterResoDaughterNeg[] = "CprV0DaughterResoDaughterNeg";
102103
constexpr const char PrefixCprTrackCascadeBachelor[] = "CprTrackCascadeBachelor";
104+
constexpr const char PrefixCprMcParticleMcParticle[] = "CprMcParticleMcParticle";
103105

104106
// pairs
105107
using ConfCprTrackTrack = ConfCpr<PrefixCprTrackTrack>;
@@ -117,6 +119,7 @@ using ConfCprV0DaugherV0DaughterNeg = ConfCpr<PrefixCprV0DaughterV0DaughterNeg>;
117119
using ConfCprV0DaughterResoDaughterPos = ConfCpr<PrefixCprV0DaughterResoDaughterPos>;
118120
using ConfCprV0DaughterResoDaughterNeg = ConfCpr<PrefixCprV0DaughterResoDaughterNeg>;
119121
using ConfCprTrackCascadeBachelor = ConfCpr<PrefixCprTrackCascadeBachelor>;
122+
using ConfCprMcParticleMcParticle = ConfCpr<PrefixCprMcParticleMcParticle, false>; // generated particles, no cut by default
120123

121124
// tpc radii for computing phistar
122125
constexpr int Nradii = 9;

‎PWGCF/Femto/Core/collisionBuilder.h‎

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ struct ConfCollisionFilters : o2::framework::ConfigurableGroup {
6262

6363
struct ConfCollisionBits : o2::framework::ConfigurableGroup {
6464
std::string prefix = std::string("CollisionBits");
65-
o2::framework::Configurable<bool> passThrough{"passThrough", false, "If true, all tracks are passed through. Bits for all selections are stored."};
65+
o2::framework::Configurable<bool> passThrough{"passThrough", false, "If true, all collisions are passed through. Bits for all enabled (non-zero) selection flags are stored, disabled flags (0) are not."};
6666
o2::framework::Configurable<int> sel8{"sel8", 1, "Use sel8 (-1: stored in bitmaks; 0 off; 1 on)"};
67+
o2::framework::Configurable<int> rctFlags{"rctFlags", 1, "RCT flags ok, checker configured via CollisionRctFlags (-1: stored in bitmaks; 0 off; 1 on)"};
6768
o2::framework::Configurable<int> noSameBunchPileup{"noSameBunchPileup", 0, "Reject collisions in case of pileup with another collision in the same foundBC (-1: stored in bitmaks; 0 off; 1 on)"};
6869
o2::framework::Configurable<int> isVertexItsTpc{"isVertexItsTpc", 0, "At least one ITS-TPC track found for the vertex (-1: stored in bitmaks; 0 off; 1 on)"};
6970
o2::framework::Configurable<int> isGoodZvtxFt0VsPv{"isGoodZvtxFt0VsPv", 0, "small difference between z-vertex from PV and from FT0 (-1: stored in bitmaks; 0 off; 1 on)"};
@@ -81,9 +82,9 @@ struct ConfCollisionBits : o2::framework::ConfigurableGroup {
8182
o2::framework::Configurable<std::vector<float>> sphericityMin{"sphericityMin", {}, "Minimum sphericity"};
8283
o2::framework::Configurable<std::vector<float>> sphericityMax{"sphericityMax", {}, "Maximum sphericity"};
8384
o2::framework::Configurable<std::vector<std::string>> triggers{"triggers", {}, "List of all triggers to be used"};
84-
o2::framework::Configurable<datatypes::EventShapeDetectorType> eventPlaneAngleDetector{"eventPlaneAngleDetector", 0, "Detector used to estimate the event plane angle: 0 -> FT0C, 1 -> FT0A"};
85-
o2::framework::Configurable<datatypes::EventShapeDetectorType> qvecDetector{"qvecDetector", 0, "Detector used to estimate the Q-vector: 0 -> FT0C, 1 -> FT0A"};
86-
o2::framework::Configurable<datatypes::QvecHarmonicType> qvecHarmonic{"qvecHarmonic", 2, "Harmonic n of the Q-vector and event plane angle Psi_n: 2 -> elliptic, 3 -> triangular"};
85+
o2::framework::Configurable<int> eventPlaneAngleDetector{"eventPlaneAngleDetector", 0, "Detector used to estimate the event plane angle: 0 -> FT0C, 1 -> FT0A"};
86+
o2::framework::Configurable<int> qvecDetector{"qvecDetector", 0, "Detector used to estimate the Q-vector: 0 -> FT0C, 1 -> FT0A"};
87+
o2::framework::Configurable<int> qvecHarmonic{"qvecHarmonic", 2, "Harmonic n of the Q-vector and event plane angle Psi_n: 2 -> elliptic, 3 -> triangular"};
8788
};
8889

8990
struct ConfCcdb : o2::framework::ConfigurableGroup {
@@ -96,7 +97,6 @@ struct ConfCcdb : o2::framework::ConfigurableGroup {
9697

9798
struct ConfCollisionRctFlags : o2::framework::ConfigurableGroup {
9899
std::string prefix = std::string("CollisionRctFlags");
99-
o2::framework::Configurable<bool> useRctFlags{"useRctFlags", true, "Set to true to use RCT flags"};
100100
o2::framework::Configurable<std::string> label{"label", std::string("CBT_hadronPID"), "Which RCT flag to check"};
101101
o2::framework::Configurable<bool> useZdc{"useZdc", false, "Whether to use ZDC (only use for PbPb)"};
102102
o2::framework::Configurable<bool> treatLimitedAcceptanceAsBad{"treatLimitedAcceptanceAsBad", false, "Whether to treat limited acceptance as bad or not"};
@@ -120,6 +120,7 @@ struct ConfCollisionSelection : o2::framework::ConfigurableGroup {
120120
enum CollisionSels {
121121
// collsion selection flags
122122
kSel8, ///< Sel8
123+
kRctFlags, ///< RCT flags ok
123124
kNoSameBunchPileUp, ///< Reject collisions in case of pileup with another collision in the same foundBC
124125
kIsVertexItsTpc, ///< At least one ITS-TPC track found for the vertex
125126
kIsGoodZvtxFt0VsPv, ///< small difference between z-vertex from PV and from FT0
@@ -146,6 +147,7 @@ constexpr char ColSelHistName[] = "hCollisionSelection";
146147
const char colSelsName[] = "Collision Selection Object";
147148
const std::unordered_map<CollisionSels, std::string> collisionSelectionNames = {
148149
{kSel8, "Sel8"},
150+
{kRctFlags, "RCT flags ok"},
149151
{kNoSameBunchPileUp, "No same bunch pileup"},
150152
{kIsVertexItsTpc, "Is vertex ITS TPC"},
151153
{kIsGoodZvtxFt0VsPv, "Is good zvtx FT0 vs PV"},
@@ -176,7 +178,6 @@ enum CollisionFilters {
176178
kFilterMagFieldMax,
177179
kFilterSphericityMin,
178180
kFilterSphericityMax,
179-
kFilterRctFlags,
180181
kFilterCollisionFiltersMax
181182
};
182183

@@ -191,8 +192,7 @@ const std::unordered_map<CollisionFilters, std::string> collisionFilterNames = {
191192
{kFilterMagFieldMin, "magFieldMin"},
192193
{kFilterMagFieldMax, "magFieldMax"},
193194
{kFilterSphericityMin, "sphericityMin"},
194-
{kFilterSphericityMax, "sphericityMax"},
195-
{kFilterRctFlags, "rctFlagsOkFilter"}};
195+
{kFilterSphericityMax, "sphericityMax"}};
196196

197197
template <auto& SelectionHistName, auto& FilterHistName>
198198
class CollisionSelection : public baseselection::BaseSelection<float, o2::analysis::femto::datatypes::CollisionMaskType, kCollisionSelsMax>
@@ -206,7 +206,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
206206
/// \param registry Histogram registry.
207207
/// \param filter ConfCollisionFilters (kinematic/quality pre-filter bounds).
208208
/// \param config ConfCollisionBits (selection bits + trigger list + event shape settings).
209-
/// \param confRct ConfCollisionRctFlags (RCT flag checker configuration).
209+
/// \param confRct ConfCollisionRctFlags (RCT flag checker configuration, used if CollisionBits.rctFlags != 0).
210210
/// \param confCcdb ConfCcdb (needed for the trigger CCDB path).
211211
template <typename T1, typename T2, typename T3, typename T4>
212212
void configure(o2::framework::HistogramRegistry* registry, T1 const& filter, T2 const& config, T3 const& confRct, T4 const& confCcdb)
@@ -225,8 +225,8 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
225225
mSphericityMin = filter.sphericityMin.value;
226226
mSphericityMax = filter.sphericityMax.value;
227227

228-
// RCT flag checker
229-
mUseRctFlags = confRct.useRctFlags.value;
228+
// RCT flag checker, only needed if the rct selection is enabled
229+
mUseRctFlags = config.rctFlags.value != 0;
230230
if (mUseRctFlags) {
231231
LOG(info) << "Init RCT flag checker with label: " << confRct.label.value << "; use ZDC: " << confRct.useZdc.value << "; Limited acceptance is bad: " << confRct.treatLimitedAcceptanceAsBad.value;
232232
mRctFlagsChecker.init(confRct.label.value, confRct.useZdc.value, confRct.treatLimitedAcceptanceAsBad.value);
@@ -261,6 +261,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
261261
}
262262

263263
this->addSelection(kSel8, collisionSelectionNames.at(kSel8), config.sel8.value);
264+
this->addSelection(kRctFlags, collisionSelectionNames.at(kRctFlags), config.rctFlags.value);
264265
this->addSelection(kNoSameBunchPileUp, collisionSelectionNames.at(kNoSameBunchPileUp), config.noSameBunchPileup.value);
265266
this->addSelection(kIsVertexItsTpc, collisionSelectionNames.at(kIsVertexItsTpc), config.isVertexItsTpc.value);
266267
this->addSelection(kIsGoodZvtxFt0VsPv, collisionSelectionNames.at(kIsGoodZvtxFt0VsPv), config.isGoodZvtxFt0VsPv.value);
@@ -296,7 +297,6 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
296297
{collisionFilterNames.at(kFilterMagFieldMax), mMagFieldMax},
297298
{collisionFilterNames.at(kFilterSphericityMin), mSphericityMin},
298299
{collisionFilterNames.at(kFilterSphericityMax), mSphericityMax},
299-
{collisionFilterNames.at(kFilterRctFlags), mUseRctFlags ? 1.f : 0.f},
300300
});
301301
}
302302

@@ -452,10 +452,6 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
452452
this->template fillFilter<FilterHistName>(kFilterSphericityMax, p);
453453
pass &= p;
454454

455-
p = !mUseRctFlags || mRctFlagsChecker(col);
456-
this->template fillFilter<FilterHistName>(kFilterRctFlags, p);
457-
pass &= p;
458-
459455
this->template fillFilterSummary<FilterHistName>(pass);
460456

461457
return this->isPassThrough() || pass;
@@ -481,6 +477,10 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
481477
this->evaluateObservable(kIsGoodItsLayer3, static_cast<float>(col.selection_bit(o2::aod::evsel::kIsGoodITSLayer3)));
482478
this->evaluateObservable(kIsGoodItsLayer0123, static_cast<float>(col.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)));
483479
this->evaluateObservable(kIsGoodItsLayerAll, static_cast<float>(col.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)));
480+
// checker is only initialized if the rct selection is enabled
481+
if (mUseRctFlags) {
482+
this->evaluateObservable(kRctFlags, static_cast<float>(mRctFlagsChecker(col)));
483+
}
484484

485485
this->evaluateObservable(kOccupancyMin, col.trackOccupancyInTimeRange());
486486
this->evaluateObservable(kOccupancyMax, col.trackOccupancyInTimeRange());
@@ -581,7 +581,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
581581

582582
// RCT flags
583583
mutable aod::rctsel::RCTFlagsChecker mRctFlagsChecker;
584-
bool mUseRctFlags = false;
584+
bool mUseRctFlags = false; // true if CollisionBits.rctFlags != 0
585585

586586
// trigger (Zorro)
587587
Zorro mZorro;
@@ -770,6 +770,7 @@ class CollisionBuilder
770770
collisionProducts.producedMultiplicityEstimators(
771771
col.multFT0A(),
772772
col.multFT0C(),
773+
col.numContrib(),
773774
col.multNTracksPVeta1(),
774775
col.multNTracksPVetaHalf(),
775776
col.trackOccupancyInTimeRange(),
@@ -817,6 +818,7 @@ class CollisionBuilder
817818

818819
[[nodiscard]] bool fillAnyTable() const { return mFillAnyTable; }
819820
[[nodiscard]] bool isPassThrough() const { return mCollisionSelection.isPassThrough(); }
821+
[[nodiscard]] int subGeneratorId() const { return mSubGeneratorId; }
820822
[[nodiscard]] bool producingCollisions() const { return mProducedCollisions; }
821823
[[nodiscard]] bool producingLiteCollisions() const { return mProducedLiteCollisions; }
822824

0 commit comments

Comments
 (0)