2323
2424#include < Rtypes.h>
2525
26+ #include < algorithm>
2627#include < array>
2728#include < cstdint>
2829#include < iostream>
@@ -39,11 +40,19 @@ class MixingHandler : public TNamed
3940 float eta;
4041 float phi;
4142 uint32_t filteringFlags;
43+ // globalIndex is unique only within a dataframe, so the dataframe sequence is part of the track identity
44+ uint64_t dataFrameSequence = 0 ;
45+ uint64_t trackGlobalIndex = 0 ;
46+ bool IsSamePhysicalTrack (const MixingTrack& other) const
47+ {
48+ return dataFrameSequence == other.dataFrameSequence && trackGlobalIndex == other.trackGlobalIndex ;
49+ }
4250 // Clear a bit once the track was used in mixing for that bit for the required pool depth.
4351 void ClearBit (uint32_t mask) { filteringFlags &= ~mask; }
4452 void Print () const
4553 {
46- std::cout << " pt: " << pt << " , eta: " << eta << " , phi: " << phi << " , filteringFlags: " << filteringFlags << std::endl;
54+ std::cout << " pt: " << pt << " , eta: " << eta << " , phi: " << phi << " , filteringFlags: " << filteringFlags
55+ << " , dataframe: " << dataFrameSequence << " , track: " << trackGlobalIndex << std::endl;
4756 }
4857 };
4958
@@ -70,6 +79,19 @@ class MixingHandler : public TNamed
7079 }
7180 // Clear bits in the filtering mask.
7281 void ClearFilteringMask (uint32_t mask) { filteringMask &= ~mask; }
82+ // clear the cut bits from all tracks and the filtering mask; remove tracks with no active bits left
83+ void ClearBits (uint32_t mask)
84+ {
85+ for (auto & track : tracks1) {
86+ track.ClearBit (mask);
87+ }
88+ tracks1.erase (std::remove_if (tracks1.begin (), tracks1.end (), [](auto const & track) { return track.filteringFlags == 0 ; }), tracks1.end ());
89+ for (auto & track : tracks2) {
90+ track.ClearBit (mask);
91+ }
92+ tracks2.erase (std::remove_if (tracks2.begin (), tracks2.end (), [](auto const & track) { return track.filteringFlags == 0 ; }), tracks2.end ());
93+ ClearFilteringMask (mask);
94+ }
7395 // 1) increment the counters for a given track cut bit mask and if the counters reached the pool depth,
7496 // 2) clear the corresponding bit in the tracks filtering flags to exclude them from further mixing
7597 // 3) for each track, if there are no more active bits in the filtering mask, then remove the track from the event
@@ -157,6 +179,35 @@ class MixingHandler : public TNamed
157179 CleanPool ();
158180 events.push_back (event);
159181 }
182+ // fixed-block mixing: AddEvent() until GetMixingMask() reports full cuts, mix, then ClearBits()
183+ void AddEvent (const MixingEvent& event) { events.push_back (event); }
184+ // bit mask of the cuts for which at least poolDepth events are in the pool
185+ uint32_t GetMixingMask (int16_t poolDepth) const
186+ {
187+ std::array<int16_t , 32 > counts = {0 };
188+ for (auto const & event : events) {
189+ for (int icut = 0 ; icut < 32 ; ++icut) {
190+ if (event.filteringMask & (static_cast <uint32_t >(1 ) << icut)) {
191+ counts[icut]++;
192+ }
193+ }
194+ }
195+ uint32_t fullMask = 0 ;
196+ for (int icut = 0 ; icut < 32 ; ++icut) {
197+ if (counts[icut] >= poolDepth) {
198+ fullMask |= static_cast <uint32_t >(1 ) << icut;
199+ }
200+ }
201+ return fullMask;
202+ }
203+ // clear the given cut bits from all events in the pool and remove the events with no tracks left
204+ void ClearBits (uint32_t mask)
205+ {
206+ for (auto & event : events) {
207+ event.ClearBits (mask);
208+ }
209+ CleanPool ();
210+ }
160211 // getter for the events in the pool
161212 const std::vector<MixingEvent>& GetEvents () const { return events; }
162213
@@ -176,17 +227,22 @@ class MixingHandler : public TNamed
176227 // setters
177228 void AddMixingVariable (int var, const std::vector<float >& binLims);
178229 void SetPoolDepth (int16_t depth) { fPoolDepth = depth; }
230+ // remove all pools (e.g. at a run change)
231+ void ClearPools () { fPools .clear (); }
179232
180233 // getters
181234 // int GetNMixingVariables() const { return fVariables.size(); }
182235 // int GetMixingVariable(VarManager::Variables var); // returns the position in the internal varible list of the handler. Useful for checks, mostly
183236 // std::vector<float> GetMixingVariableLimits(VarManager::Variables var);
184237 MixingPool& GetPool (int category) { return fPools [category]; }
238+ std::map<int , MixingPool>& GetPools () { return fPools ; }
185239 int16_t GetPoolDepth () const { return fPoolDepth ; }
186240
187241 void Init ();
188242 int FindEventCategory (float * values);
189243 int GetBinFromCategory (VarManager::Variables var, int category) const ;
244+ // set the mixing variables to the bin centers of the given category
245+ void SetCategoryBinCenters (int category, float * values) const ;
190246
191247 private:
192248 MixingHandler (const MixingHandler& handler);
0 commit comments