Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 109 additions & 85 deletions PWGCF/Femto/Core/pairBuilder.h

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions PWGCF/Femto/Core/pairHistManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ struct ConfMixing : o2::framework::ConfigurableGroup {
o2::framework::ConfigurableAxis eventPlaneAngle{"eventPlaneAngle", {10, 0.f, 1.f * o2::constants::math::TwoPI}, "Mixing bins - event plane angle"};
o2::framework::Configurable<int> depth{"depth", 5, "Number of events for mixing"};
o2::framework::Configurable<int> policy{"policy", 0, "Binning policy for mixing (alywas in combination with z-vertex) -> 0: multiplicity, -> 1: centrality, -> 2: multiplicity and centrality, -> 3: centrality and event plane angle"};
o2::framework::Configurable<int> eventStride{"eventStride", 1, "Only use every Nth collision as a mixing anchor (1 = use every collision). Reduces mixed-event combinatorics roughly 1/eventStride."};
o2::framework::Configurable<bool> sameSpecies{"sameSpecies", false, "Enable if particle 1 and particle 2 are the same"};
o2::framework::Configurable<int> seed{"seed", -1, "Seed to randomize particle 1 and particle 2 (if they are identical). Set to negative value to deactivate. Set to 0 to generate unique seed in time."};
o2::framework::Configurable<bool> enablePairCorrelationQa{"enablePairCorrelationQa", true, "Enable pair-level correlation QA (same-event + mixed-event)"};
Expand Down
66 changes: 57 additions & 9 deletions PWGCF/Femto/Core/pairProcessHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,11 +439,16 @@ void processMixedEvent(T1 const& Collisions,
T7 const& depth,
T8& PairHistManager,
T9& CprManager,
T10& PcManager)
T10& PcManager,
int eventStride = 1)
{
int64_t lastCollisionIndex = -1;
int windowSizeRaw = 0;
int windowSizeEffective = 0;
// counts actual anchor windows encountered (not raw collision IDs, which may have gaps from
// upstream event selection) so "every Nth anchor" is evenly spaced regardless of such gaps
int64_t windowCounter = -1;
bool skipThisWindow = false;

// collision1 is fixed across each mixing window, so its track slice is
// materialized once per window and reused for every mixing partner, instead
Expand All @@ -455,13 +460,24 @@ void processMixedEvent(T1 const& Collisions,

// --- new window ---
if (collision1.globalIndex() != lastCollisionIndex) {
if (lastCollisionIndex != -1) {
if (lastCollisionIndex != -1 && !skipThisWindow) {
PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective);
}
windowSizeRaw = 0;
windowSizeEffective = 0;
lastCollisionIndex = collision1.globalIndex();
sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache));
++windowCounter;
// skip entire anchor windows to reduce mixed-event combinatorics without truncating any
// single event's particle content -- every anchor that IS processed still gets its full
// `depth` worth of mixing partners
skipThisWindow = eventStride > 1 && windowCounter % eventStride != 0;
if (!skipThisWindow) {
sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache));
}
}

if (skipThisWindow) {
continue;
}

++windowSizeRaw;
Expand Down Expand Up @@ -551,11 +567,16 @@ void processMixedEvent(T1 const& Collisions,
T13& ParticleCleaner1,
T14& ParticleCleaner2,
T15& CprManager,
T16& PcManager)
T16& PcManager,
int eventStride = 1)
{
int64_t lastCollisionIndex = -1;
int windowSizeRaw = 0;
int windowSizeEffective = 0;
// counts actual anchor windows encountered (not raw collision IDs, which may have gaps from
// upstream event selection) so "every Nth anchor" is evenly spaced regardless of such gaps
int64_t windowCounter = -1;
bool skipThisWindow = false;

// collision1 is fixed across each mixing window, so its track slice is
// materialized once per window and reused for every mixing partner, instead
Expand All @@ -565,13 +586,24 @@ void processMixedEvent(T1 const& Collisions,

for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) {
if (collision1.globalIndex() != lastCollisionIndex) {
if (lastCollisionIndex != -1) {
if (lastCollisionIndex != -1 && !skipThisWindow) {
PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective);
}
windowSizeRaw = 0;
windowSizeEffective = 0;
lastCollisionIndex = collision1.globalIndex();
sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache));
++windowCounter;
// skip entire anchor windows to reduce mixed-event combinatorics without truncating any
// single event's particle content -- every anchor that IS processed still gets its full
// `depth` worth of mixing partners
skipThisWindow = eventStride > 1 && windowCounter % eventStride != 0;
if (!skipThisWindow) {
sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache));
}
}

if (skipThisWindow) {
continue;
}

++windowSizeRaw;
Expand Down Expand Up @@ -661,24 +693,40 @@ void processMixedEvent(T1 const& Collisions,
T11& ParticleCleaner1,
T12& ParticleCleaner2,
T13& CprManager,
T14& PcManager)
T14& PcManager,
int eventStride = 1)
{
int64_t lastCollisionIndex = -1;
int windowSizeRaw = 0;
int windowSizeEffective = 0;
// counts actual anchor windows encountered (not raw collision IDs, which may have gaps from
// upstream event selection) so "every Nth anchor" is evenly spaced regardless of such gaps
int64_t windowCounter = -1;
bool skipThisWindow = false;

std::optional<decltype(Partition1->sliceByCachedUnsorted(o2::aod::femtomcparticle::fMcColId, 0, cache))> sliceParticle1;

for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) {

if (collision1.globalIndex() != lastCollisionIndex) {
if (lastCollisionIndex != -1) {
if (lastCollisionIndex != -1 && !skipThisWindow) {
PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective);
}
windowSizeRaw = 0;
windowSizeEffective = 0;
lastCollisionIndex = collision1.globalIndex();
sliceParticle1.emplace(Partition1->sliceByCachedUnsorted(o2::aod::femtomcparticle::fMcColId, collision1.globalIndex(), cache));
++windowCounter;
// skip entire anchor windows to reduce mixed-event combinatorics without truncating any
// single event's particle content -- every anchor that IS processed still gets its full
// `depth` worth of mixing partners
skipThisWindow = eventStride > 1 && windowCounter % eventStride != 0;
if (!skipThisWindow) {
sliceParticle1.emplace(Partition1->sliceByCachedUnsorted(o2::aod::femtomcparticle::fMcColId, collision1.globalIndex(), cache));
}
}

if (skipThisWindow) {
continue;
}

++windowSizeRaw;
Expand Down
Loading
Loading