Skip to content

Commit f1a5bff

Browse files
authored
add occupancy-related structures and enums to EventSelection
1 parent 1a83e8a commit f1a5bff

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

‎Common/DataModel/EventSelection.h‎

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#define COMMON_DATAMODEL_EVENTSELECTION_H_
1919

2020
#include <Framework/AnalysisDataModel.h>
21+
#include <Framework/Logger.h>
22+
23+
#include <algorithm>
24+
#include <cstdint>
25+
#include <ranges>
26+
#include <vector>
2127

2228
namespace o2::aod
2329
{
@@ -85,6 +91,105 @@ DECLARE_SOA_TABLE(EvSels, "AOD", "EVSEL", //!
8591
evsel::SumAmpFT0CInTimeRange,
8692
evsel::OccupancyMedianTime);
8793
using EvSel = EvSels::iterator;
94+
95+
// occupancy wrt BCs: same estimators and flags as in EvSels (occupancy from other collisions nearby in time),
96+
// calculated wrt a BC; collisions found in this BC are excluded (their number is stored in numCollsInBC)
97+
// N.B.: not related to the occupancy tables in OccupancyTables.h
98+
namespace bcocc
99+
{
100+
enum BcOccupancyFlags { // bits of occupancyFlags
101+
kNoCollInTimeRangeNarrow = 0, // no other collisions in specified time range (narrower than Strict)
102+
kNoCollInTimeRangeStrict, // no other collisions in specified time range
103+
kNoCollInTimeRangeStandard, // no other collisions in specified time range with per-collision multiplicity above threshold
104+
kNoCollInRofStrict, // no other collisions in this ITS Readout Frame
105+
kNoCollInRofStandard, // no other collisions in this ITS Readout Frame with per-collision multiplicity above threshold (no veto on collisions with close vZ)
106+
kNoHighMultCollInPrevRof // FT0C amplitude in previous ITS ROF is below threshold
107+
};
108+
DECLARE_SOA_COLUMN(NumTracksInTimeRange, trackOccupancyInTimeRange, int); //! Occupancy in specified time interval by a number of tracks from nearby collisions (-1 if not available) // o2-linter: disable=name/o2-column
109+
DECLARE_SOA_COLUMN(SumAmpFT0CInTimeRange, ft0cOccupancyInTimeRange, float); //! Occupancy in specified time interval by a sum of FT0C amplitudes from nearby collisions (-1 if not available) // o2-linter: disable=name/o2-column
110+
DECLARE_SOA_COLUMN(OccupancyMedianTime, occupancyMedianTime, float); //! Median time for the occupancy in specified time interval (the delta-time wrt to the BC at which occupancy crosses 1/2 of its full value)
111+
DECLARE_SOA_BITMAP_COLUMN(OccupancyFlags, occupancyFlags, 8); //! Bitmask of occupancy flags (see BcOccupancyFlags), check with occupancyFlags_bit(bit)
112+
DECLARE_SOA_COLUMN(NumCollsInBC, numCollsInBC, int16_t); //! Number of collisions found in this BC (excluded from the occupancy)
113+
} // namespace bcocc
114+
115+
// bc-joinable occupancy
116+
DECLARE_SOA_TABLE(BcOccs, "AOD", "BCOCC", //!
117+
bcocc::NumTracksInTimeRange,
118+
bcocc::SumAmpFT0CInTimeRange,
119+
bcocc::OccupancyMedianTime,
120+
bcocc::OccupancyFlags,
121+
bcocc::NumCollsInBC);
122+
using BcOcc = BcOccs::iterator;
123+
124+
// occupancy wrt every BC of the TFs present in the DF (not joinable): for each TF (in increasing order) all its BCs, in increasing order of global BC
125+
// same estimators and flags as in BcOccs
126+
DECLARE_SOA_TABLE(BcOccsAll, "AOD", "BCOCCALL", //!
127+
bc::GlobalBC,
128+
bcocc::NumTracksInTimeRange,
129+
bcocc::SumAmpFT0CInTimeRange,
130+
bcocc::OccupancyMedianTime,
131+
bcocc::OccupancyFlags,
132+
bcocc::NumCollsInBC);
133+
using BcOccAll = BcOccsAll::iterator;
134+
135+
namespace bcocc
136+
{
137+
// fast lookup of the aod::BcOccsAll entry for a given global BC
138+
// usage (within the process function, the index keeps a pointer to the table):
139+
// aod::bcocc::BcOccAllIndex bcOccAllIndexed(bcOccsAll);
140+
// auto occ = bcOccAllIndexed[bc.globalBC()]; // iterator of aod::BcOccsAll
141+
// int occByTracks = occ.trackOccupancyInTimeRange();
142+
template <typename TBcOccsAll>
143+
class BcOccAllIndex
144+
{
145+
public:
146+
explicit BcOccAllIndex(TBcOccsAll const& bcOccsAll) : mTable(&bcOccsAll)
147+
{
148+
const int64_t nRows = static_cast<int64_t>(bcOccsAll.size());
149+
auto offsetAt = [&bcOccsAll](int64_t row) { return static_cast<int64_t>(bcOccsAll.iteratorAt(row).globalBC()) - row; };
150+
for (int64_t first = 0, end = 0; first < nRows; first = end) {
151+
// the offset is non-decreasing (global BCs are strictly increasing): the segment ends at the first row with a larger offset
152+
const int64_t offset = offsetAt(first);
153+
end = *std::ranges::partition_point(std::views::iota(first, nRows), [&](int64_t row) { return offsetAt(row) == offset; });
154+
mSegments.push_back({offset + first, offset + end, offset});
155+
}
156+
}
157+
158+
// entry of aod::BcOccsAll for this global BC (fatal if the BC is not in the table)
159+
auto operator[](uint64_t globalBC) const
160+
{
161+
const int64_t row = rowOf(globalBC);
162+
if (row < 0) {
163+
LOGP(fatal, "BcOccAllIndex: global BC {} is not in aod::BcOccsAll ({} rows): its TF is not in this DF, or the occupancy is not available for this DF", globalBC, mTable->size());
164+
}
165+
return mTable->iteratorAt(row);
166+
}
167+
168+
// helper function to check if a global BC is contained in the table
169+
bool contains(uint64_t globalBC) const { return rowOf(globalBC) >= 0; }
170+
171+
private:
172+
// row of aod::BcOccsAll for this global BC, -1 if the BC is not in the table
173+
int64_t rowOf(uint64_t globalBC) const
174+
{
175+
const auto bc = static_cast<int64_t>(globalBC);
176+
for (const auto& seg : mSegments) { // a few segments: one per range of consecutive TFs in the DF
177+
if (bc >= seg.firstGlobalBC && bc < seg.endGlobalBC) {
178+
return bc - seg.offset;
179+
}
180+
}
181+
return -1;
182+
}
183+
184+
struct Segment {
185+
int64_t firstGlobalBC; // first global BC of the segment
186+
int64_t endGlobalBC; // last global BC of the segment + 1
187+
int64_t offset; // globalBC - row, constant within the segment
188+
};
189+
TBcOccsAll const* mTable; // not owned: the index is valid as long as the table (within the process function)
190+
std::vector<Segment> mSegments; // in increasing order of global BC
191+
};
192+
} // namespace bcocc
88193
} // namespace o2::aod
89194

90195
#endif // COMMON_DATAMODEL_EVENTSELECTION_H_

0 commit comments

Comments
 (0)