Skip to content

Commit e92b77d

Browse files
committed
back to rolling mixing
1 parent 287a879 commit e92b77d

3 files changed

Lines changed: 77 additions & 193 deletions

File tree

PWGDQ/Core/MixingHandler.cxx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,18 +194,3 @@ int MixingHandler::GetBinFromCategory(VarManager::Variables var, int category) c
194194
truncatedCategory /= norm;
195195
return truncatedCategory % nBins[ivar];
196196
}
197-
198-
//_________________________________________________________________________
199-
void MixingHandler::SetCategoryBinCenters(int category, float* values) const
200-
{
201-
//
202-
// set the mixing variables to the bin centers of this category (used for the leftover mixing)
203-
//
204-
for (auto const& [var, pos] : fVariables) {
205-
int bin = GetBinFromCategory(static_cast<VarManager::Variables>(var), category);
206-
if (bin < 0) {
207-
continue;
208-
}
209-
values[var] = 0.5 * (fVariableLimits[pos][bin] + fVariableLimits[pos][bin + 1]);
210-
}
211-
}

PWGDQ/Core/MixingHandler.h

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
#include <Rtypes.h>
2525

26-
#include <algorithm>
2726
#include <array>
2827
#include <cstdint>
2928
#include <iostream>
@@ -36,8 +35,6 @@ class MixingHandler : public TNamed
3635
public:
3736
// number of track cuts which fit in the 32-bit filtering masks
3837
static constexpr int NMaxCuts = 32;
39-
// smallest pool depth for which a mixed pair can be built
40-
static constexpr int16_t MinPoolDepth = 2;
4138

4239
// Struct to define track properties relevant for mixing and few utility functions
4340
struct MixingTrack {
@@ -48,6 +45,8 @@ class MixingHandler : public TNamed
4845
// globalIndex is unique only within a dataframe, so the dataframe sequence is part of the track identity
4946
uint64_t dataFrameSequence = 0;
5047
uint64_t trackGlobalIndex = 0;
48+
// electric charge of the track; 0 means "not set" and disables the charge dependent pair variables
49+
int8_t sign = 0;
5150
bool IsSamePhysicalTrack(const MixingTrack& other) const
5251
{
5352
return dataFrameSequence == other.dataFrameSequence && trackGlobalIndex == other.trackGlobalIndex;
@@ -56,7 +55,8 @@ class MixingHandler : public TNamed
5655
void ClearBit(uint32_t mask) { filteringFlags &= ~mask; }
5756
void Print() const
5857
{
59-
std::cout << "pt: " << pt << ", eta: " << eta << ", phi: " << phi << ", filteringFlags: " << filteringFlags
58+
std::cout << "pt: " << pt << ", eta: " << eta << ", phi: " << phi << ", sign: " << static_cast<int>(sign)
59+
<< ", filteringFlags: " << filteringFlags
6060
<< ", dataframe: " << dataFrameSequence << ", track: " << trackGlobalIndex << std::endl;
6161
}
6262
};
@@ -84,19 +84,6 @@ class MixingHandler : public TNamed
8484
}
8585
// Clear bits in the filtering mask.
8686
void ClearFilteringMask(uint32_t mask) { filteringMask &= ~mask; }
87-
// clear the cut bits from all tracks and the filtering mask; remove tracks with no active bits left
88-
void ClearBits(uint32_t mask)
89-
{
90-
for (auto& track : tracks1) {
91-
track.ClearBit(mask);
92-
}
93-
tracks1.erase(std::remove_if(tracks1.begin(), tracks1.end(), [](auto const& track) { return track.filteringFlags == 0; }), tracks1.end());
94-
for (auto& track : tracks2) {
95-
track.ClearBit(mask);
96-
}
97-
tracks2.erase(std::remove_if(tracks2.begin(), tracks2.end(), [](auto const& track) { return track.filteringFlags == 0; }), tracks2.end());
98-
ClearFilteringMask(mask);
99-
}
10087
// 1) increment the counters for a given track cut bit mask and if the counters reached the pool depth,
10188
// 2) clear the corresponding bit in the tracks filtering flags to exclude them from further mixing
10289
// 3) for each track, if there are no more active bits in the filtering mask, then remove the track from the event
@@ -184,34 +171,16 @@ class MixingHandler : public TNamed
184171
CleanPool();
185172
events.push_back(event);
186173
}
187-
// fixed-block mixing: AddEvent() until GetMixingMask() reports full cuts, mix, then ClearBits()
188-
void AddEvent(const MixingEvent& event) { events.push_back(event); }
189-
// bit mask of the cuts for which at least poolDepth events are in the pool
190-
uint32_t GetMixingMask(int16_t poolDepth) const
174+
// Same, but the stored events are aged only for the cuts in agingMask. Passing the filtering mask of the
175+
// incoming event ages an event only for the cuts for which a mixed pair was actually produced, so that the
176+
// pool depth is a number of mixed partners and not a number of arrivals.
177+
void UpdatePool(const MixingEvent& event, int16_t poolDepth, uint32_t agingMask)
191178
{
192-
std::array<int16_t, NMaxCuts> counts = {0};
193-
for (auto const& event : events) {
194-
for (int icut = 0; icut < NMaxCuts; ++icut) {
195-
if (event.filteringMask & (static_cast<uint32_t>(1) << icut)) {
196-
counts[icut]++;
197-
}
198-
}
199-
}
200-
uint32_t fullMask = 0;
201-
for (int icut = 0; icut < NMaxCuts; ++icut) {
202-
if (counts[icut] >= poolDepth) {
203-
fullMask |= static_cast<uint32_t>(1) << icut;
204-
}
205-
}
206-
return fullMask;
207-
}
208-
// clear the given cut bits from all events in the pool and remove the events with no tracks left
209-
void ClearBits(uint32_t mask)
210-
{
211-
for (auto& event : events) {
212-
event.ClearBits(mask);
179+
for (auto& poolEvent : events) { // o2-linter: disable=const-ref-in-for-loop (the events are modified)
180+
poolEvent.IncrementCounters(agingMask, poolDepth);
213181
}
214182
CleanPool();
183+
events.push_back(event);
215184
}
216185
// getter for the events in the pool
217186
const std::vector<MixingEvent>& GetEvents() const { return events; }
@@ -240,14 +209,11 @@ class MixingHandler : public TNamed
240209
// int GetMixingVariable(VarManager::Variables var); // returns the position in the internal varible list of the handler. Useful for checks, mostly
241210
// std::vector<float> GetMixingVariableLimits(VarManager::Variables var);
242211
MixingPool& GetPool(int category) { return fPools[category]; }
243-
std::map<int, MixingPool>& GetPools() { return fPools; }
244212
int16_t GetPoolDepth() const { return fPoolDepth; }
245213

246214
void Init();
247215
int FindEventCategory(float* values);
248216
int GetBinFromCategory(VarManager::Variables var, int category) const;
249-
// set the mixing variables to the bin centers of the given category
250-
void SetCategoryBinCenters(int category, float* values) const;
251217

252218
private:
253219
MixingHandler(const MixingHandler& handler);

PWGDQ/Tasks/tableReader_withAssoc.h

Lines changed: 66 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
#include <cstdio>
7474
#include <cstdlib>
7575
#include <cstring>
76-
#include <functional>
7776
#include <iterator>
7877
#include <map>
7978
#include <memory>
@@ -82,26 +81,6 @@
8281
#include <variant>
8382
#include <vector>
8483

85-
// OutputObj with a callback run on the first dereference, i.e. right before the end-of-stream snapshot
86-
// (tasks cannot register their own EndOfStream callback, CallbackService::set replaces the framework one)
87-
template <typename T>
88-
struct FinalizingOutputObj : public o2::framework::OutputObj<T> {
89-
using o2::framework::OutputObj<T>::OutputObj;
90-
std::function<void()> finalizeBeforeSnapshot;
91-
bool finalized = false;
92-
93-
T& operator*()
94-
{
95-
if (!finalized) {
96-
finalized = true;
97-
if (finalizeBeforeSnapshot) {
98-
finalizeBeforeSnapshot();
99-
}
100-
}
101-
return o2::framework::OutputObj<T>::operator*();
102-
}
103-
};
104-
10584
// Some definitions
10685
namespace o2::aod
10786
{
@@ -1376,7 +1355,7 @@ struct AnalysisSameEventPairing {
13761355
TH1D* ResoFlowEP = nullptr;
13771356
int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc.
13781357

1379-
FinalizingOutputObj<THashList> fOutputList{"output"};
1358+
o2::framework::OutputObj<THashList> fOutputList{"output"};
13801359

13811360
struct : o2::framework::ConfigurableGroup {
13821361
o2::framework::Configurable<std::string> track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"};
@@ -1741,9 +1720,6 @@ struct AnalysisSameEventPairing {
17411720
}
17421721

17431722
if (fConfigRunMixingAcrossTFs) {
1744-
if (fConfigMixingDepth.value < MixingHandler::MinPoolDepth) {
1745-
LOGF(fatal, "cfgMixingDepth must be at least %d", MixingHandler::MinPoolDepth);
1746-
}
17471723
if (fNCutsBarrel > MixingHandler::NMaxCuts) {
17481724
LOGF(fatal, "Across-TF mixing supports at most %d barrel track-cut bits, got %d", MixingHandler::NMaxCuts, fNCutsBarrel);
17491725
}
@@ -1849,12 +1825,6 @@ struct AnalysisSameEventPairing {
18491825
o2::aod::dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON
18501826
VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill
18511827
fOutputList.setObject(fHistMan->GetMainHistogramList());
1852-
// mix the events left in the pools at the end of the stream
1853-
fOutputList.finalizeBeforeSnapshot = [this]() {
1854-
if (fConfigRunMixingAcrossTFs) {
1855-
runLeftoverMixing();
1856-
}
1857-
};
18581828
}
18591829
}
18601830

@@ -1932,97 +1902,6 @@ struct AnalysisSameEventPairing {
19321902
}
19331903
}
19341904

1935-
// Mix all the events in the pool for the cuts in mixingMask (event-wise variables are those of the current event)
1936-
void runEventMixing(MixingHandler::MixingPool& pool, uint32_t mixingMask)
1937-
{
1938-
auto const& events = pool.GetEvents();
1939-
// each pair of events is mixed once
1940-
for (size_t iev1 = 0; iev1 < events.size(); iev1++) {
1941-
for (size_t iev2 = iev1 + 1; iev2 < events.size(); iev2++) {
1942-
auto const& mixingEvent = events[iev1];
1943-
auto const& poolEvent = events[iev2];
1944-
if (!(mixingEvent.filteringMask & poolEvent.filteringMask & mixingMask)) {
1945-
continue;
1946-
}
1947-
for (auto const& t1 : mixingEvent.tracks1) {
1948-
// run +- pairing
1949-
for (auto const& t2 : poolEvent.tracks2) {
1950-
// check the two-track filter for the mixed pair
1951-
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags & mixingMask;
1952-
if (!mixedTwoTrackFilter) {
1953-
continue;
1954-
}
1955-
VarManager::FillPairMEAcrossTFs(t1, t2);
1956-
for (int icut = 0; icut < fNCutsBarrel; icut++) {
1957-
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
1958-
fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
1959-
}
1960-
}
1961-
}
1962-
// run ++ pairing
1963-
for (auto const& t2 : poolEvent.tracks1) {
1964-
// check the two-track filter for the mixed pair and skip the same track associated to both collisions
1965-
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags & mixingMask;
1966-
if (!mixedTwoTrackFilter || t1.IsSamePhysicalTrack(t2)) {
1967-
continue;
1968-
}
1969-
VarManager::FillPairMEAcrossTFs(t1, t2);
1970-
for (int icut = 0; icut < fNCutsBarrel; icut++) {
1971-
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
1972-
fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
1973-
}
1974-
}
1975-
}
1976-
}
1977-
for (auto const& t1 : mixingEvent.tracks2) {
1978-
// run -+ pairing
1979-
for (auto const& t2 : poolEvent.tracks1) {
1980-
// check the two-track filter for the mixed pair
1981-
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags & mixingMask;
1982-
if (!mixedTwoTrackFilter) {
1983-
continue;
1984-
}
1985-
VarManager::FillPairMEAcrossTFs(t1, t2);
1986-
for (int icut = 0; icut < fNCutsBarrel; icut++) {
1987-
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
1988-
fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
1989-
}
1990-
}
1991-
}
1992-
// run -- pairing
1993-
for (auto const& t2 : poolEvent.tracks2) {
1994-
// check the two-track filter for the mixed pair and skip the same track associated to both collisions
1995-
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags & mixingMask;
1996-
if (!mixedTwoTrackFilter || t1.IsSamePhysicalTrack(t2)) {
1997-
continue;
1998-
}
1999-
VarManager::FillPairMEAcrossTFs(t1, t2);
2000-
for (int icut = 0; icut < fNCutsBarrel; icut++) {
2001-
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
2002-
fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
2003-
}
2004-
}
2005-
}
2006-
}
2007-
}
2008-
}
2009-
}
2010-
2011-
// Mix the events left in the pools (end of stream or run change), with the mixing variables set to the category bin centers
2012-
void runLeftoverMixing()
2013-
{
2014-
for (auto& [category, pool] : fMixingHandler.GetPools()) { // o2-linter: disable=const-ref-in-for-loop (the pools are modified)
2015-
const uint32_t mixingMask = pool.GetMixingMask(MixingHandler::MinPoolDepth);
2016-
if (!mixingMask) {
2017-
continue;
2018-
}
2019-
VarManager::ResetValues(0, VarManager::kNEventWiseVariables);
2020-
fMixingHandler.SetCategoryBinCenters(category, dqtablereader_helpers::varValues());
2021-
runEventMixing(pool, mixingMask);
2022-
pool.ClearBits(mixingMask);
2023-
}
2024-
}
2025-
20261905
// Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon)
20271906
template <bool TTwoProngFitter, int TPairType, uint32_t TEventFillMap, uint32_t TTrackFillMap, typename TEvents, typename TTrackAssocs, typename TTracks>
20281907
void runSameEventPairing(TEvents const& events, o2::framework::Preslice<TTrackAssocs>& preslice, TTrackAssocs const& assocs, TTracks const& /*tracks*/)
@@ -2031,9 +1910,6 @@ struct AnalysisSameEventPairing {
20311910
if (fCurrentRun != events.begin().runNumber()) {
20321911
if (fConfigRunMixingAcrossTFs) {
20331912
// do not mix events from different runs
2034-
if (fCurrentRun >= 0) {
2035-
runLeftoverMixing();
2036-
}
20371913
fMixingHandler.ClearPools();
20381914
}
20391915
initParamsFromCCDB(events.begin().timestamp(), events.begin().runNumber(), TTwoProngFitter);
@@ -2636,7 +2512,7 @@ struct AnalysisSameEventPairing {
26362512
continue;
26372513
}
26382514
auto t1 = assoc.template reducedtrack_as<TTracks>();
2639-
MixingHandler::MixingTrack mixingTrack(t1.pt(), t1.eta(), t1.phi(), trackFilterForMixing, currentMixingDataFrameSequence, static_cast<uint64_t>(assoc.reducedtrackId()));
2515+
MixingHandler::MixingTrack mixingTrack(t1.pt(), t1.eta(), t1.phi(), trackFilterForMixing, currentMixingDataFrameSequence, static_cast<uint64_t>(assoc.reducedtrackId()), static_cast<int8_t>(t1.sign()));
26402516
if (t1.sign() > 0) {
26412517
mixingEvent.AddTrack1(mixingTrack);
26422518
} else {
@@ -2647,15 +2523,72 @@ struct AnalysisSameEventPairing {
26472523
if (mixingEvent.tracks1.empty() && mixingEvent.tracks2.empty()) {
26482524
continue;
26492525
}
2650-
// 2) add the event to the pool corresponding to this event
2526+
// 2) run the mixing with the events in the pool corresponding to this event
26512527
auto& pool = fMixingHandler.GetPool(mixingCategory);
2652-
pool.AddEvent(mixingEvent);
2653-
// 3) mix all the events in the pool for the cuts which reached the pool depth
2654-
uint32_t mixingMask = pool.GetMixingMask(fMixingHandler.GetPoolDepth());
2655-
if (mixingMask) {
2656-
runEventMixing(pool, mixingMask);
2657-
pool.ClearBits(mixingMask);
2528+
for (auto const& poolEvent : pool.GetEvents()) {
2529+
for (auto const& t1 : mixingEvent.tracks1) {
2530+
// run +- pairing
2531+
for (auto const& t2 : poolEvent.tracks2) {
2532+
// check the two-track filter for the mixed pair
2533+
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags;
2534+
if (!mixedTwoTrackFilter) {
2535+
continue;
2536+
}
2537+
VarManager::FillPairMEAcrossTFs(t1, t2);
2538+
for (int icut = 0; icut < ncuts; icut++) {
2539+
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
2540+
fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
2541+
}
2542+
}
2543+
}
2544+
// run ++ pairing
2545+
for (auto const& t2 : poolEvent.tracks1) {
2546+
// check the two-track filter for the mixed pair and skip the same track associated to both collisions
2547+
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags;
2548+
if (!mixedTwoTrackFilter || t1.IsSamePhysicalTrack(t2)) {
2549+
continue;
2550+
}
2551+
VarManager::FillPairMEAcrossTFs(t1, t2);
2552+
for (int icut = 0; icut < ncuts; icut++) {
2553+
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
2554+
fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
2555+
}
2556+
}
2557+
}
2558+
}
2559+
for (auto const& t1 : mixingEvent.tracks2) {
2560+
// run -+ pairing
2561+
for (auto const& t2 : poolEvent.tracks1) {
2562+
// check the two-track filter for the mixed pair
2563+
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags;
2564+
if (!mixedTwoTrackFilter) {
2565+
continue;
2566+
}
2567+
VarManager::FillPairMEAcrossTFs(t1, t2);
2568+
for (int icut = 0; icut < ncuts; icut++) {
2569+
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
2570+
fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
2571+
}
2572+
}
2573+
}
2574+
// run -- pairing
2575+
for (auto const& t2 : poolEvent.tracks2) {
2576+
// check the two-track filter for the mixed pair and skip the same track associated to both collisions
2577+
uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags;
2578+
if (!mixedTwoTrackFilter || t1.IsSamePhysicalTrack(t2)) {
2579+
continue;
2580+
}
2581+
VarManager::FillPairMEAcrossTFs(t1, t2);
2582+
for (int icut = 0; icut < ncuts; icut++) {
2583+
if (mixedTwoTrackFilter & (static_cast<uint32_t>(1) << icut)) {
2584+
fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues());
2585+
}
2586+
}
2587+
}
2588+
}
26582589
}
2590+
// 3) add the current event to the pool
2591+
pool.UpdatePool(mixingEvent, fMixingHandler.GetPoolDepth(), mixingEvent.filteringMask);
26592592
// pool.Print();
26602593
}
26612594
} // end loop over events

0 commit comments

Comments
 (0)