Skip to content

Commit 9c15284

Browse files
authored
[PWGCF] Fixes in femto framework (#18494)
1 parent a0adddb commit 9c15284

3 files changed

Lines changed: 34 additions & 12 deletions

File tree

‎PWGCF/Femto/Core/collisionBuilder.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct ConfCollisionFilters : o2::framework::ConfigurableGroup {
5757
o2::framework::Configurable<float> sphericityMax{"sphericityMax", 1.f, "Maximum sphericity"};
5858
o2::framework::Configurable<int> magFieldMin{"magFieldMin", -5, "Minimum magnetic field strength (kG)"};
5959
o2::framework::Configurable<int> magFieldMax{"magFieldMax", 5, "Maximum magnetic field strength (kG)"};
60-
o2::framework::Configurable<int> subGeneratorId{"subGeneratorId", 0, "MC ONLY: Sub-generator ID to keep (0 = MB). Only applied if >= 0; set to -1 (default) to disable and keep all sub-generators"};
60+
o2::framework::Configurable<int> subGeneratorId{"subGeneratorId", -1, "MC ONLY: Sub-generator ID to keep (0 = MB). Only applied if >= 0; set to -1 (default) to disable and keep all sub-generators"};
6161
};
6262

6363
struct ConfCollisionBits : o2::framework::ConfigurableGroup {

‎PWGCF/Femto/Core/dndetaBuilder.h‎

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ class DndetaBuilder
232232
/// - reco: for every mc collision only the reconstructed collision with the most PV contributors is used
233233
/// (emulates bestCollisionIndex); it has to pass the full event selection including the reco trigger
234234
/// - gen: efficiency histograms for all generated collisions, loss histograms for the generated event class
235-
/// (vertex z, optional INEL>0, optional generator-level trigger)
235+
/// (optional INEL>0, optional generator-level trigger); the loss block's reco requirement is Sel8
236+
/// only (no vtxZ, see isSelectedByMaskOnly), the vtxZ cut only gates the efficiency block above
236237
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
237238
void processMc(T1 const& cols,
238239
T2 const& mcCols,
@@ -263,11 +264,20 @@ class DndetaBuilder
263264
}
264265

265266
// reconstructed side
267+
// selectedReco: full "selvtx" selection (Sel8 + |vtxZ| < cut + trigger), feeds the Gen-efficiency block (Ctrk)
268+
// hasSel8Reco: "sel" selection (Sel8 only, no vtxZ, no trigger), feeds the event/signal loss block (Csel);
269+
// per the analysis note, Csel's Gsel/Esel correspond to the Sel8 class only, Cvtx (the vtxZ-related bias) is
270+
// not implemented (every Run3 event with a vertex is already within the stored range), so the loss-block
271+
// reco requirement must not carry the vtxZ cut like the Ctrk-side "selvtx" one does
266272
std::vector<int64_t> selectedReco(nMcCols, -1);
273+
std::vector<bool> hasSel8Reco(nMcCols, false);
267274
for (auto const& col : cols) {
268275
if (!col.has_fMcCol() || bestReco[static_cast<std::size_t>(col.fMcColId())] != col.globalIndex()) {
269276
continue;
270277
}
278+
if (isSelectedByMaskOnly(col)) {
279+
hasSel8Reco[static_cast<std::size_t>(col.fMcColId())] = true;
280+
}
271281
if (!selectCollision(col, [&]() {
272282
return recoTrigger(col);
273283
})) {
@@ -300,13 +310,12 @@ class DndetaBuilder
300310
}
301311
}
302312

303-
// event and signal loss: generated event class, true centrality
313+
// event and signal loss: generated event class (INEL or INEL>0), true centrality
314+
// Gall/Gsel (and Eall/Esel) are defined by the analysis note without any vtxZ restriction - the vtxZ
315+
// cut belongs only to Ctrk's "selvtx" quantities above, so it is intentionally not applied here
304316
if (!mDoMcLoss) {
305317
continue;
306318
}
307-
if (mcCol.posZ() < mVtxZMin || mcCol.posZ() > mVtxZMax) {
308-
continue;
309-
}
310319
int nChMult = 0;
311320
int nChEta1 = 0;
312321
for (auto const& particle : particles) {
@@ -324,13 +333,14 @@ class DndetaBuilder
324333
if (mUseGenTrigger && !genTrigger(mcCol)) {
325334
continue;
326335
}
336+
const bool hasSel8RecoForLoss = hasSel8Reco[mcColIndex];
327337
const auto mult = static_cast<float>(nChMult);
328-
mHistManager.fillLossEvent(mcCol.cent(), mult, hasSelectedReco);
338+
mHistManager.fillLossEvent(mcCol.cent(), mult, hasSel8RecoForLoss);
329339
for (auto const& particle : particles) {
330340
if (!isGenParticleSelected(particle, pdg)) {
331341
continue;
332342
}
333-
mHistManager.fillLossParticle(particle.eta(), mcCol.cent(), mult, hasSelectedReco);
343+
mHistManager.fillLossParticle(particle.eta(), mcCol.cent(), mult, hasSel8RecoForLoss);
334344
}
335345
}
336346
}
@@ -353,6 +363,18 @@ class DndetaBuilder
353363
LOG(info) << name << ": pT range " << conf.ptMin.value << " - " << conf.ptMax.value << " GeV/c, eta range " << conf.etaMin.value << " - " << conf.etaMax.value;
354364
}
355365

366+
/// selected by maks only class (no vtxZ, no INEL>0, no trigger; pure predicate, no cutflow side effects), used to
367+
/// build Gsel/Esel of the event/signal loss block - kept separate from selectCollision() below, whose
368+
/// vtxZ-gated "selvtx" result must not be reused for the loss block (see processMc)
369+
template <typename T>
370+
bool isSelectedByMaskOnly(T const& col) const
371+
{
372+
return col.mult() >= mMultMin && col.mult() <= mMultMax &&
373+
col.cent() >= mCentMin && col.cent() <= mCentMax &&
374+
col.magField() >= mMagFieldMin && col.magField() <= mMagFieldMax &&
375+
(col.mask() & mCollisionMask) == mCollisionMask;
376+
}
377+
356378
/// event selection with cutflow; the trigger is evaluated last, so the trigger QA
357379
/// only contains events that passed all other event selections
358380
template <typename T1, typename T2>

‎PWGCF/Femto/Core/trackBuilder.h‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ struct ConfTrackBits : o2::framework::ConfigurableGroup {
129129
};
130130

131131
// define the template structure for TrackSelection
132-
template <auto& Prefix>
132+
template <auto& Prefix, int DefaultChargeSign = 1>
133133
struct ConfTrackSelection : public o2::framework::ConfigurableGroup {
134134
std::string prefix = Prefix; // Unique prefix based on the template argument
135135
// configuration parameters
136136
o2::framework::Configurable<int> pdgCodeAbs{"pdgCodeAbs", 2212, "Absolute value of PDG code. Set sign of charge to -1 for antiparticle."};
137137
o2::framework::Configurable<int> chargeAbs{"chargeAbs", 1, "Absolute value of charge (e.g. 1 for most tracks, 2 for He3)"};
138-
o2::framework::Configurable<int> chargeSign{"chargeSign", 1, "Track charge sign: +1 for positive, -1 for negative, 0 for both"};
138+
o2::framework::Configurable<int> chargeSign{"chargeSign", DefaultChargeSign, "Track charge sign: +1 for positive, -1 for negative, 0 for both"};
139139
// filters for kinematics
140140
o2::framework::Configurable<float> ptMin{"ptMin", 0.0f, "Minimum pT (GeV/c)"};
141141
o2::framework::Configurable<float> ptMax{"ptMax", 6.f, "Maximum pT (GeV/c)"};
@@ -170,8 +170,8 @@ using ConfTrackSelection1 = ConfTrackSelection<PrefixTrackSelection1>;
170170
using ConfTrackSelection2 = ConfTrackSelection<PrefixTrackSelection2>;
171171
using ConfTrackSelection3 = ConfTrackSelection<PrefixTrackSelection3>;
172172

173-
using ConfTrackSelectionDndetaGlobal = ConfTrackSelection<PrefixTrackSelectionDndetaGlobal>;
174-
using ConfTrackSelectionDndetaItsOnly = ConfTrackSelection<PrefixTrackSelectionDndetaItsOnly>;
173+
using ConfTrackSelectionDndetaGlobal = ConfTrackSelection<PrefixTrackSelectionDndetaGlobal, 0>;
174+
using ConfTrackSelectionDndetaItsOnly = ConfTrackSelection<PrefixTrackSelectionDndetaItsOnly, 0>;
175175

176176
// Track selection for resonance daughters (pion+/-, kaon+/-). Charge sign and abs charge are fixed
177177
// by the species itself, so they are compile-time constants rather than configurables. No pdg code

0 commit comments

Comments
 (0)