Skip to content

Commit 759302e

Browse files
committed
Reservoir sampling for event mixing of leading particles (commit preceding major changes for leading jet and subleading jet event mixing, which will change some things in the structure of the code)
1 parent 88d07f0 commit 759302e

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

PWGLF/TableProducer/Strangeness/lambdaJetPolarizationIons.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ struct lambdajetpolarizationions {
774774
histos.add("AntiLambda/hAntiLambdasPerEvent", "hAntiLambdasPerEvent;N_{#bar{#Lambda}} per event;Counts", kTH1D, {{15, 0, 15}});
775775
}
776776
if (analyseLambda && analyseAntiLambda) {
777-
histos.add("hAmbiguousLambdaCandidates", "hAmbiguousLambdaCandidates;Integrated counts;Counts", kTH1D, {{1, 0, 1}});
777+
// histos.add("hAmbiguousLambdaCandidates", "hAmbiguousLambdaCandidates;Integrated counts;Counts", kTH1D, {{1, 0, 1}}); // No longer required: v0 selection flow already considers this
778778
histos.add("hAmbiguousPerEvent", "hAmbiguousPerEvent;N_{ambiguous} per event;Counts", kTH1D, {{15, 0, 15}});
779779
histos.add("hNonAmbiguousPerEvent", "hNonAmbiguousPerEvent;N_{non-ambiguous} per event;Counts", kTH1D, {{25, 0, 25}}); // To understand the population of correlated Lambda-likes per event
780780
histos.add("hLambdasAndAntiLambdasPerEvent", "hLambdasAndAntiLambdasPerEvent;N_{#Lambda}+N_{#bar{#Lambda}} per event;Counts", kTH1D, {{25, 0, 25}}); // Alternative check that shows how bad is the possibly correlated full population (Ambig+NonAmbig)
@@ -1896,7 +1896,7 @@ struct lambdajetpolarizationions {
18961896
// int lambdaIdx = -1; // No need to pass armenteros
18971897
if (isLambda && isAntiLambda) {
18981898
NAmbiguous++;
1899-
histos.fill(HIST("hAmbiguousLambdaCandidates"), 0);
1899+
// histos.fill(HIST("hAmbiguousLambdaCandidates"), 0);
19001900
if (doArmenterosQA)
19011901
histos.fill(HIST("GeneralQA/h2dArmenterosFullSelectedAmbiguous"), v0.alpha(), v0.qtarm()); // To know the discerning power of Armenteros in an Ambiguous Lambda vs AntiLambda case
19021902

PWGLF/Tasks/Strangeness/lambdaJetPolarizationIonsDerived.cxx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,17 +1281,28 @@ struct lambdajetpolarizationionsderived {
12811281
SameKindPair<o2::aod::RingCollisions, o2::aod::RingLeadPs, MixBinningType> mixPair{
12821282
mixBinning, fakePolSwitches.mixedEventLeadPWindowSize, -1, collisions, std::make_tuple(leadPs), &mixCache};
12831283

1284-
// "Last neighbour wins" if a collision appears in more than one pair within its window -- simple and
1285-
// deterministic, not a uniform-random pick among the window's members:
1284+
// Uniform random pick among each target's candidate window, via reservoir sampling
1285+
// (cannibalization of leading particles by neighbouring collisions in Continuous Readout is not a worry as ITS hits are being demanded)
1286+
std::unordered_map<int64_t, int> mixedLeadPCandidateCount; // how many candidates seen so far, per target
1287+
auto reservoirInsert = [this, &mixedLeadPCandidateCount, &mixedLeadPByCollision](int64_t targetId, const MixedLeadPInfo& candidate) {
1288+
int& nSeen = mixedLeadPCandidateCount[targetId];
1289+
++nSeen;
1290+
// The n-th candidate seen for a given target replaces the current pick with probability 1/n, so we never need more than one cached candidate:
1291+
std::uniform_int_distribution<int> pick(1, nSeen);
1292+
if (pick(rng) == 1) // Reuses the same rng member as forceRandJet/forceDatalikeJet, rather than a second generator.
1293+
mixedLeadPByCollision[targetId] = candidate;
1294+
};
1295+
12861296
for (auto it = mixPair.begin(); it != mixPair.end(); ++it) {
12871297
auto& [c1, leadP1, c2, leadP2] = *it; // Iterates over collision pairs and leading particle pairs (structured binding)
12881298
if (leadP1.size() > 0 && leadP2.size() > 0) { // There should always be at least one leadP, given the overflow exclusion above
12891299
float eta1 = 0.f, phi1 = 0.f, eta2 = 0.f, phi2 = 0.f;
12901300
for (auto const& lp : leadP1) { eta1 = lp.leadParticleEta(); phi1 = lp.leadParticlePhi(); break; } // Retrieves the first entry
12911301
for (auto const& lp : leadP2) { eta2 = lp.leadParticleEta(); phi2 = lp.leadParticlePhi(); break; }
1292-
// Saving the mixed leading particles with a key referring to the two collisions being mixed:
1293-
mixedLeadPByCollision[c1.globalIndex()] = {eta2, phi2, c2.globalIndex()};
1294-
mixedLeadPByCollision[c2.globalIndex()] = {eta1, phi1, c1.globalIndex()};
1302+
// Each side of the pair is one more candidate for the other collision's reservoir:
1303+
// (after that, saves the mixed leading particles with a key referring to the two collisions being mixed)
1304+
reservoirInsert(c1.globalIndex(), {eta2, phi2, c2.globalIndex()});
1305+
reservoirInsert(c2.globalIndex(), {eta1, phi1, c1.globalIndex()});
12951306
}
12961307
if (it.isNewWindow()) { // Count each bin-window once, not once per pair inside it
12971308
histos.fill(HIST("JetKinematicsQA/hMixedEventLeadPWindowNeighbours"), it.currentWindowNeighbours());
@@ -1359,9 +1370,8 @@ struct lambdajetpolarizationionsderived {
13591370
float leadPEta = 0.;
13601371
float leadPPhi = 0.;
13611372
float leadPPx = 0., leadPPy = 0., leadPPz = 0.;
1362-
for (auto const& lp : leadPsInColl) {
1363-
// Table should contain exactly one entry per collision,
1364-
// but we break immediately to be safe:
1373+
for (auto const& lp : leadPsInColl) { //
1374+
// Table should contain exactly one entry per collision, but we break immediately to be safe:
13651375
leadPPt = lp.leadParticlePt();
13661376
leadPEta = lp.leadParticleEta();
13671377
leadPPhi = lp.leadParticlePhi();

0 commit comments

Comments
 (0)