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
27 changes: 21 additions & 6 deletions PWGDQ/Core/MixingHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ void MixingHandler::AddMixingVariable(int var, const std::vector<float>& binLims
{
fVariables[var] = fVariableLimits.size();
fVariableLimits.push_back(binLims);
// FillEvent() only fills variables marked as used
VarManager::SetUseVariable(var);
}

/*
Expand Down Expand Up @@ -125,13 +127,16 @@ int MixingHandler::FindEventCategory(float* values)

// loop over the variables and find out in which bin the value of the variable for the event is located
std::vector<int> bin;
// number of bins per variable in the iteration order of fVariables (fVariableLimits is in insertion order)
std::vector<int> nBins;
for (auto [var, pos] : fVariables) {
// check that the value is within limits, if not return -1 to exclude the event from mixing
size_t binValue = std::distance(fVariableLimits[pos].begin(), std::upper_bound(fVariableLimits[pos].begin(), fVariableLimits[pos].end(), values[var]));
if (binValue == 0 || binValue == fVariableLimits[pos].size()) {
return -1; // all variables must be inside limits
}
bin.push_back(binValue - 1);
nBins.push_back(fVariableLimits[pos].size() - 1);
}

// Hash the bin values to define a unique category
Expand All @@ -149,7 +154,7 @@ int MixingHandler::FindEventCategory(float* values)
if (iv2 == iv1) {
tempCategory *= bin[iv2];
} else {
tempCategory *= (fVariableLimits[iv2].size() - 1);
tempCategory *= nBins[iv2];
}
}
category += tempCategory;
Expand All @@ -167,15 +172,25 @@ int MixingHandler::GetBinFromCategory(VarManager::Variables var, int category) c
return -1;
}

// Search for the position of the variable "var" in the internal variable list of the handler
int ivar = fVariables.at(var);
// number of bins and position of var in the iteration order of fVariables, as used by FindEventCategory()
std::vector<int> nBins;
int ivar = -1;
for (auto const& [v, pos] : fVariables) {
if (v == var) {
ivar = static_cast<int>(nBins.size());
}
nBins.push_back(fVariableLimits[pos].size() - 1);
}
if (ivar < 0) {
return -1;
}

// extract the bin position in variable "var" from the category
int norm = 1;
for (int i = fVariables.size() - 1; i > ivar; --i) {
norm *= (fVariableLimits[i].size() - 1);
for (size_t i = nBins.size() - 1; i > static_cast<size_t>(ivar); --i) {
norm *= nBins[i];
}
int truncatedCategory = category - (category % norm);
truncatedCategory /= norm;
return truncatedCategory % (fVariableLimits[ivar].size() - 1);
return truncatedCategory % nBins[ivar];
}
16 changes: 16 additions & 0 deletions PWGDQ/Core/MixingHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class MixingHandler : public TNamed
{

public:
// number of track cuts which fit in the 32-bit filtering masks
static constexpr int NMaxCuts = 32;

// Struct to define track properties relevant for mixing and few utility functions
struct MixingTrack {
float pt;
Expand Down Expand Up @@ -157,6 +160,17 @@ class MixingHandler : public TNamed
CleanPool();
events.push_back(event);
}
// Same, but the stored events are aged only for the cuts in agingMask. Passing the filtering mask of the
// incoming event ages an event only for the cuts for which a mixed pair was actually produced, so that the
// pool depth is a number of mixed partners and not a number of arrivals.
void UpdatePool(const MixingEvent& event, int16_t poolDepth, uint32_t agingMask)
{
for (auto& poolEvent : events) {
poolEvent.IncrementCounters(agingMask, poolDepth);
}
CleanPool();
events.push_back(event);
}
// getter for the events in the pool
const std::vector<MixingEvent>& GetEvents() const { return events; }

Expand All @@ -176,6 +190,8 @@ class MixingHandler : public TNamed
// setters
void AddMixingVariable(int var, const std::vector<float>& binLims);
void SetPoolDepth(int16_t depth) { fPoolDepth = depth; }
// remove all pools (e.g. at a run change)
void ClearPools() { fPools.clear(); }

// getters
// int GetNMixingVariables() const { return fVariables.size(); }
Expand Down
4 changes: 4 additions & 0 deletions PWGDQ/Tasks/tableReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ struct AnalysisEventSelection {

if (fMixHandler != nullptr) {
int hh = fMixHandler->FindEventCategory(VarManager::fgValues);
// events outside the mixing limits (-1) get a distinct negative hash so that they are not mixed with each other
if (hh < 0) {
hh = -1 - static_cast<int>(event.globalIndex());
}
hash(hh);
}
}
Expand Down
25 changes: 23 additions & 2 deletions PWGDQ/Tasks/tableReader_withAssoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,10 @@ struct AnalysisEventSelection {
// create the mixing hash and publish it into the hash table
if (fMixHandler != nullptr) {
int hh = fMixHandler->FindEventCategory(dqtablereader_helpers::varValues());
// events outside the mixing limits (-1) get a distinct negative hash so that they are not mixed with each other
if (hh < 0) {
hh = -1 - static_cast<int>(event.globalIndex());
}
hash(hh);
}
}
Expand Down Expand Up @@ -1714,6 +1718,9 @@ struct AnalysisSameEventPairing {
}

if (fConfigRunMixingAcrossTFs) {
if (fNCutsBarrel > MixingHandler::NMaxCuts) {
LOGF(fatal, "Across-TF mixing supports at most %d barrel track-cut bits, got %d", MixingHandler::NMaxCuts, fNCutsBarrel);
}
TString mixVarsString = fConfigMixingVariables.value;
TString mixVarsJsonString = fConfigMixingVariablesJson.value;
std::unique_ptr<TObjArray> objArray(mixVarsString.Tokenize(","));
Expand Down Expand Up @@ -1899,6 +1906,10 @@ struct AnalysisSameEventPairing {
{
if (events.size() > 0) { // Additional protection to avoid crashing of events.begin().runNumber()
if (fCurrentRun != events.begin().runNumber()) {
if (fConfigRunMixingAcrossTFs) {
// do not mix events from different runs
fMixingHandler.ClearPools();
}
initParamsFromCCDB(events.begin().timestamp(), events.begin().runNumber(), TTwoProngFitter);
fCurrentRun = events.begin().runNumber();
}
Expand Down Expand Up @@ -2006,6 +2017,10 @@ struct AnalysisSameEventPairing {
}
VarManager::FillEventFlowResoFactor(ResoFlowSP, ResoFlowEP);
}
int mixingCategory = -1;
if (fConfigRunMixingAcrossTFs) {
mixingCategory = fMixingHandler.FindEventCategory(dqtablereader_helpers::varValues());
}

bool isFirst = true;
for (auto const& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) {
Expand Down Expand Up @@ -2478,6 +2493,9 @@ struct AnalysisSameEventPairing {

if (fConfigRunMixingAcrossTFs) {
// run event mixing across TFs
if (mixingCategory < 0) {
continue;
}
// 1) create a MixingEvent and fill it with the relevant tracks
MixingHandler::MixingEvent mixingEvent;
uint32_t trackFilterForMixing = 0;
Expand All @@ -2496,8 +2514,11 @@ struct AnalysisSameEventPairing {
}
}
}
if (mixingEvent.tracks1.empty() && mixingEvent.tracks2.empty()) {
continue;
}
// 2) run the mixing with the events in the pool corresponding to this event
auto& pool = fMixingHandler.GetPool(fMixingHandler.FindEventCategory(dqtablereader_helpers::varValues()));
auto& pool = fMixingHandler.GetPool(mixingCategory);
for (auto const& poolEvent : pool.GetEvents()) {
for (auto const& t1 : mixingEvent.tracks1) {
// run +- pairing
Expand Down Expand Up @@ -2561,7 +2582,7 @@ struct AnalysisSameEventPairing {
}
}
// 3) add the current event to the pool
pool.UpdatePool(mixingEvent, fMixingHandler.GetPoolDepth());
pool.UpdatePool(mixingEvent, fMixingHandler.GetPoolDepth(), mixingEvent.filteringMask);
// pool.Print();
}
} // end loop over events
Expand Down
14 changes: 10 additions & 4 deletions PWGDQ/Tasks/tableReader_withAssoc_direct.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,16 @@ struct AnalysisEventSelection {
VarManager::FillBC(bc);
VarManager::FillEvent<TEventFillMap>(event);

// the hash table is joined to the events by row order, so publish one row per event before any event selection
if (fMixHandler != nullptr) {
int hh = fMixHandler->FindEventCategory(VarManager::fgValues);
// events outside the mixing limits (-1) get a distinct negative hash so that they are not mixed with each other
if (hh < 0) {
hh = -1 - static_cast<int>(event.globalIndex());
}
hash(hh);
}

bool decision = false;
if (fConfigQA) {
fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues);
Expand Down Expand Up @@ -533,10 +543,6 @@ struct AnalysisEventSelection {
auto& evIndices = fBCCollMap[bc.globalBC()];
evIndices.push_back(event.globalIndex());
}
if (fMixHandler != nullptr) {
int hh = fMixHandler->FindEventCategory(VarManager::fgValues);
hash(hh);
}
}
}

Expand Down
Loading