Skip to content

Commit b3b74b3

Browse files
authored
[PWGLF] Add optimized mixed event process function (#12152)
1 parent 8d9773d commit b3b74b3

File tree

1 file changed

+126
-30
lines changed

1 file changed

+126
-30
lines changed

PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx

Lines changed: 126 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Framework/ASoAHelpers.h"
2323
#include "Framework/AnalysisDataModel.h"
2424
#include "Framework/AnalysisTask.h"
25+
#include "Framework/BinningPolicy.h"
2526
#include "Framework/StepTHn.h"
2627
#include "Framework/runDataProcessing.h"
2728
#include <Framework/Configurable.h>
@@ -34,9 +35,15 @@
3435

3536
#include <fairlogger/Logger.h>
3637

38+
#include <cmath> // for std::fabs
39+
#include <deque>
3740
#include <iostream>
3841
#include <iterator>
42+
#include <set> // <<< CHANGED: for dedup sets
3943
#include <string>
44+
#include <type_traits>
45+
#include <unordered_map> // <<< CHANGED: for seenMap
46+
#include <utility>
4047
#include <vector>
4148

4249
// o2 includes.
@@ -49,7 +56,7 @@ using namespace o2::framework::expressions;
4956
using namespace o2::soa;
5057

5158
struct lambdaspincorrderived {
52-
59+
// BinningType colBinning;
5360
struct : ConfigurableGroup {
5461
Configurable<std::string> cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"};
5562
Configurable<int64_t> nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"};
@@ -71,6 +78,7 @@ struct lambdaspincorrderived {
7178
Configurable<float> centMax{"centMax", 80, "Maximum Centrality"};
7279

7380
// Lambda selection ////////////
81+
Configurable<unsigned> harmonic{"harmonic", 1, "Harmonic delta phi"};
7482
Configurable<bool> useweight{"useweight", 1, "Use weight"};
7583
Configurable<bool> usePDGM{"usePDGM", 1, "Use PDG mass"};
7684
Configurable<bool> checkDoubleStatus{"checkDoubleStatus", 0, "Check Double status"};
@@ -183,7 +191,7 @@ struct lambdaspincorrderived {
183191
if (std::abs(candidate1.lambdaEta() - candidate2.lambdaEta()) > etaMix) {
184192
return false;
185193
}
186-
if (std::abs(RecoDecay::constrainAngle(candidate1.lambdaPhi(), 0.0F) - RecoDecay::constrainAngle(candidate2.lambdaPhi(), 0.0F)) > phiMix) {
194+
if (std::abs(RecoDecay::constrainAngle(candidate1.lambdaPhi(), 0.0F, harmonic) - RecoDecay::constrainAngle(candidate2.lambdaPhi(), 0.0F, harmonic)) > phiMix) {
187195
return false;
188196
}
189197
if (std::abs(candidate1.lambdaMass() - candidate2.lambdaMass()) > massMix) {
@@ -195,7 +203,7 @@ struct lambdaspincorrderived {
195203
void fillHistograms(int tag1, int tag2,
196204
const ROOT::Math::PtEtaPhiMVector& particle1, const ROOT::Math::PtEtaPhiMVector& particle2,
197205
const ROOT::Math::PtEtaPhiMVector& daughpart1, const ROOT::Math::PtEtaPhiMVector& daughpart2,
198-
double centrality, int datatype)
206+
double centrality, int datatype, float mixpairweight)
199207
{
200208

201209
auto lambda1Mass = 0.0;
@@ -230,41 +238,42 @@ struct lambdaspincorrderived {
230238

231239
auto cosThetaDiff = -999.0;
232240
cosThetaDiff = proton1LambdaRF.Vect().Unit().Dot(proton2LambdaRF.Vect().Unit());
233-
double deltaPhi = std::abs(RecoDecay::constrainAngle(particle1Dummy.Phi(), 0.0F) - RecoDecay::constrainAngle(particle2Dummy.Phi(), 0.0F));
241+
double deltaPhi = std::abs(RecoDecay::constrainAngle(particle1Dummy.Phi(), 0.0F, harmonic) - RecoDecay::constrainAngle(particle2Dummy.Phi(), 0.0F, harmonic));
234242
double deltaEta = particle1Dummy.Eta() - particle2Dummy.Eta();
235243
double deltaR = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi);
236244

237245
if (datatype == 0) {
238-
histos.fill(HIST("hPtYSame"), particle1.Pt(), particle1.Rapidity());
246+
mixpairweight = 1.0;
247+
histos.fill(HIST("hPtYSame"), particle1.Pt(), particle1.Rapidity(), mixpairweight);
239248
if (tag1 == 0 && tag2 == 0) {
240-
histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR);
241-
histos.fill(HIST("hLambdaSameForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F));
249+
histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight);
250+
histos.fill(HIST("hLambdaSameForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight);
242251
} else if ((tag1 == 0 && tag2 == 1) || (tag1 == 1 && tag2 == 0)) {
243-
histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR);
244-
histos.fill(HIST("hLambdaSameForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F));
252+
histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight);
253+
histos.fill(HIST("hLambdaSameForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight);
245254
} else if (tag1 == 1 && tag2 == 1) {
246-
histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR);
247-
histos.fill(HIST("hAntiLambdaSameForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F));
255+
histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight);
256+
histos.fill(HIST("hAntiLambdaSameForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight);
248257
}
249258
} else if (datatype == 1) {
250-
double weight1 = 1.0;
251-
double weight2 = 1.0;
252-
double weight3 = 1.0;
259+
double weight1 = mixpairweight;
260+
double weight2 = mixpairweight;
261+
double weight3 = mixpairweight;
253262
if (useweight) {
254-
weight1 = hweight1->GetBinContent(hweight1->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
255-
weight2 = hweight2->GetBinContent(hweight2->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
256-
weight3 = hweight3->GetBinContent(hweight3->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
263+
weight1 = mixpairweight * hweight1->GetBinContent(hweight1->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
264+
weight2 = mixpairweight * hweight2->GetBinContent(hweight2->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
265+
weight3 = mixpairweight * hweight3->GetBinContent(hweight3->FindBin(particle1.Pt(), particle1.Eta(), particle1.Phi()));
257266
}
258267
histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity());
259268
if (tag1 == 0 && tag2 == 0) {
260269
histos.fill(HIST("hSparseLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight1);
261-
histos.fill(HIST("hLambdaMixForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F), weight1);
270+
histos.fill(HIST("hLambdaMixForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight1);
262271
} else if ((tag1 == 0 && tag2 == 1) || (tag1 == 1 && tag2 == 0)) {
263272
histos.fill(HIST("hSparseLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight2);
264-
histos.fill(HIST("hLambdaMixForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F), weight2);
273+
histos.fill(HIST("hLambdaMixForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight2);
265274
} else if (tag1 == 1 && tag2 == 1) {
266275
histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight3);
267-
histos.fill(HIST("hAntiLambdaMixForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F), weight3);
276+
histos.fill(HIST("hAntiLambdaMixForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight3);
268277
}
269278
}
270279
}
@@ -310,24 +319,24 @@ struct lambdaspincorrderived {
310319
}
311320
proton2 = ROOT::Math::PtEtaPhiMVector(v02.protonPt(), v02.protonEta(), v02.protonPhi(), o2::constants::physics::MassProton);
312321
lambda2 = ROOT::Math::PtEtaPhiMVector(v02.lambdaPt(), v02.lambdaEta(), v02.lambdaPhi(), v02.lambdaMass());
313-
histos.fill(HIST("deltaPhiSame"), std::abs(RecoDecay::constrainAngle(v0.lambdaPhi(), 0.0F) - RecoDecay::constrainAngle(v02.lambdaPhi(), 0.0F)));
322+
histos.fill(HIST("deltaPhiSame"), std::abs(RecoDecay::constrainAngle(v0.lambdaPhi(), 0.0F, harmonic) - RecoDecay::constrainAngle(v02.lambdaPhi(), 0.0F, harmonic)));
314323
if (std::abs(lambda2.Rapidity()) > rapidity) {
315324
continue;
316325
}
317326
if (std::abs(lambda2.Eta()) > v0eta) {
318327
continue;
319328
}
320329
if (v0.v0Status() == 0 && v02.v0Status() == 0) {
321-
fillHistograms(0, 0, lambda, lambda2, proton, proton2, centrality, 0);
330+
fillHistograms(0, 0, lambda, lambda2, proton, proton2, centrality, 0, 1.0);
322331
}
323332
if (v0.v0Status() == 0 && v02.v0Status() == 1) {
324-
fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 0);
333+
fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 0, 1.0);
325334
}
326335
if (v0.v0Status() == 1 && v02.v0Status() == 0) {
327-
fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 0);
336+
fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 0, 1.0);
328337
}
329338
if (v0.v0Status() == 1 && v02.v0Status() == 1) {
330-
fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 0);
339+
fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 0, 1.0);
331340
}
332341
}
333342
}
@@ -388,7 +397,7 @@ struct lambdaspincorrderived {
388397
lambda = ROOT::Math::PtEtaPhiMVector(t3.lambdaPt(), t3.lambdaEta(), t3.lambdaPhi(), t3.lambdaMass());
389398
proton2 = ROOT::Math::PtEtaPhiMVector(t2.protonPt(), t2.protonEta(), t2.protonPhi(), o2::constants::physics::MassProton);
390399
lambda2 = ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass());
391-
histos.fill(HIST("deltaPhiMix"), std::abs(RecoDecay::constrainAngle(t3.lambdaPhi(), 0.0F) - RecoDecay::constrainAngle(t2.lambdaPhi(), 0.0F)));
400+
histos.fill(HIST("deltaPhiMix"), std::abs(RecoDecay::constrainAngle(t3.lambdaPhi(), 0.0F, harmonic) - RecoDecay::constrainAngle(t2.lambdaPhi(), 0.0F, harmonic)));
392401
if (std::abs(lambda.Rapidity()) > rapidity) {
393402
continue;
394403
}
@@ -402,22 +411,109 @@ struct lambdaspincorrderived {
402411
continue;
403412
}
404413
if (t3.v0Status() == 0 && t2.v0Status() == 0) {
405-
fillHistograms(0, 0, lambda, lambda2, proton, proton2, centrality, 1);
414+
fillHistograms(0, 0, lambda, lambda2, proton, proton2, centrality, 1, 1.0);
406415
}
407416
if (t3.v0Status() == 0 && t2.v0Status() == 1) {
408-
fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 1);
417+
fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 1, 1.0);
409418
}
410419
if (t3.v0Status() == 1 && t2.v0Status() == 0) {
411-
fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 1);
420+
fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 1, 1.0);
412421
}
413422
if (t3.v0Status() == 1 && t2.v0Status() == 1) {
414-
fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 1);
423+
fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 1, 1.0);
415424
}
416425
}
417426
} // replacement track pair
418427
} // collision pair
419428
}
420429
PROCESS_SWITCH(lambdaspincorrderived, processME, "Process data ME", false);
430+
431+
void processMEV2(EventCandidates const& collisions, AllTrackCandidates const& V0s)
432+
{
433+
auto nBins = colBinning.getAllBinsCount();
434+
std::vector<std::deque<std::pair<int, AllTrackCandidates>>> eventPools(nBins);
435+
436+
for (auto& collision1 : collisions) {
437+
int bin = colBinning.getBin(std::make_tuple(collision1.posz(), collision1.cent()));
438+
auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index());
439+
float centrality = collision1.cent();
440+
441+
// <<< CHANGED: map old collision index → set of (t2.idx, t3.idx) we've already filled
442+
std::unordered_map<int, std::set<std::pair<int, int>>> seenMap;
443+
444+
for (auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) {
445+
if (!selectionV0(t1) || !selectionV0(t2))
446+
continue;
447+
if (t2.index() <= t1.index())
448+
continue;
449+
if (t1.protonIndex() == t2.protonIndex())
450+
continue;
451+
if (t1.pionIndex() == t2.pionIndex())
452+
continue;
453+
454+
int mixes = 0;
455+
for (auto it = eventPools[bin].rbegin(); it != eventPools[bin].rend() && mixes < nEvtMixing; ++it, ++mixes) {
456+
int collision2idx = it->first;
457+
AllTrackCandidates& poolB = it->second;
458+
459+
int nRepl = 0;
460+
for (auto& t3 : poolB) {
461+
if (selectionV0(t3) && checkKinematics(t1, t3)) {
462+
++nRepl;
463+
}
464+
}
465+
if (nRepl == 0)
466+
continue;
467+
float invN = 1.0f / static_cast<float>(nRepl);
468+
469+
for (auto& t3 : poolB) {
470+
if (!(selectionV0(t3) && checkKinematics(t1, t3))) {
471+
continue;
472+
}
473+
if (collision1.index() == collision2idx) {
474+
continue;
475+
}
476+
477+
// <<< CHANGED: dedupe (t2, t3) pairs per prior collision
478+
auto key = std::make_pair(t2.index(), t3.index());
479+
auto& seen = seenMap[collision2idx];
480+
if (!seen.insert(key).second) {
481+
continue;
482+
}
483+
484+
// reconstruct 4-vectors
485+
auto proton = ROOT::Math::PtEtaPhiMVector(t3.protonPt(), t3.protonEta(), t3.protonPhi(), o2::constants::physics::MassProton);
486+
auto lambda = ROOT::Math::PtEtaPhiMVector(t3.lambdaPt(), t3.lambdaEta(), t3.lambdaPhi(), t3.lambdaMass());
487+
auto proton2 = ROOT::Math::PtEtaPhiMVector(t2.protonPt(), t2.protonEta(), t2.protonPhi(), o2::constants::physics::MassProton);
488+
auto lambda2 = ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass());
489+
490+
float dPhi = std::fabs(RecoDecay::constrainAngle(lambda.Phi(), 0.0F, harmonic) - RecoDecay::constrainAngle(lambda2.Phi(), 0.0F, harmonic));
491+
histos.fill(HIST("deltaPhiMix"), dPhi, invN);
492+
493+
if (t3.v0Status() == 0 && t2.v0Status() == 0) {
494+
fillHistograms(0, 0, lambda, lambda2, proton, proton2, centrality, 1, invN);
495+
}
496+
if (t3.v0Status() == 0 && t2.v0Status() == 1) {
497+
fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 1, invN);
498+
}
499+
if (t3.v0Status() == 1 && t2.v0Status() == 0) {
500+
fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 1, invN);
501+
}
502+
if (t3.v0Status() == 1 && t2.v0Status() == 1) {
503+
fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 1, invN);
504+
}
505+
}
506+
} // end mixing-event loop
507+
} // end same-event pair loop
508+
509+
auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.index());
510+
eventPools[bin].emplace_back(collision1.index(), std::move(sliced));
511+
if (static_cast<int>(eventPools[bin].size()) > nEvtMixing) {
512+
eventPools[bin].pop_front();
513+
}
514+
} // end primary-event loop
515+
}
516+
PROCESS_SWITCH(lambdaspincorrderived, processMEV2, "Process data ME", false);
421517
};
422518
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
423519
{

0 commit comments

Comments
 (0)