Skip to content

Commit 4f6de0e

Browse files
committed
Feat: add range based selections
1 parent 93b44f0 commit 4f6de0e

File tree

2 files changed

+203
-76
lines changed

2 files changed

+203
-76
lines changed

PWGCF/Femto/Core/baseSelection.h

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -75,26 +75,7 @@ class BaseSelection
7575
// init selection container for selection at given index
7676
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, selectionValues, limitType, skipMostPermissiveBit, isMinimalCut, isOptionalCut);
7777

78-
// check if any selections are configured
79-
if (mSelectionContainers.at(observableIndex).isEmpty()) {
80-
return;
81-
}
82-
83-
// track the number of occupied bits and total selections
84-
mNSelectionBits += mSelectionContainers.at(observableIndex).getShift();
85-
mNSelection += mSelectionContainers.at(observableIndex).getNSelections();
86-
87-
if (mNSelectionBits > sizeof(BitmaskType) * CHAR_BIT) {
88-
LOG(fatal) << "Too many selections. At most " << sizeof(BitmaskType) * CHAR_BIT << " number of bits are supported";
89-
}
90-
// check if any selection is minimal
91-
if (mSelectionContainers.at(observableIndex).isMinimalCut()) {
92-
mHasMinimalSelection = true;
93-
}
94-
// check if selection is optional
95-
if (mSelectionContainers.at(observableIndex).isOptionalCut()) {
96-
mHasOptionalSelection = true;
97-
}
78+
init(observableIndex);
9879
}
9980

10081
/// \brief Add a function-based selection for a specific observable.
@@ -122,26 +103,32 @@ class BaseSelection
122103
}
123104
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, lowerLimit, upperLimit, functions, limitType, skipMostPermissiveBit, isMinimalCut, isOptionalCut);
124105

125-
// check if any selections are configured
126-
if (mSelectionContainers.at(observableIndex).isEmpty()) {
127-
return;
128-
}
129-
130-
// track the number of occupied bits and total selections
131-
mNSelectionBits += mSelectionContainers.at(observableIndex).getShift();
132-
mNSelection += mSelectionContainers.at(observableIndex).getNSelections();
106+
init(observableIndex);
107+
}
133108

134-
if (mNSelectionBits > sizeof(BitmaskType) * CHAR_BIT) {
135-
LOG(fatal) << "Too many selections. At most " << sizeof(BitmaskType) * CHAR_BIT << " are supported";
136-
}
137-
// check if any cut is minimal
138-
if (mSelectionContainers.at(observableIndex).isMinimalCut()) {
139-
mHasMinimalSelection = true;
140-
}
141-
// check if any selection is optional
142-
if (mSelectionContainers.at(observableIndex).isOptionalCut()) {
143-
mHasOptionalSelection = true;
109+
/// \brief Add a static-value based selection for a specific observable.
110+
/// \param observableIndex Index of the observable.
111+
/// \param selectionName Name of the selection.
112+
/// \param selectionValues Vector of threshold values.
113+
/// \param limitType Type of limit (from limits::LimitType).
114+
/// \param skipMostPermissiveBit Whether to skip the loosest threshold when assembling the bitmask.
115+
/// \param isMinimalCut Whether this cut is mandatory (must be passed for the candidate to be accepted).
116+
/// \param isOptionalCut Whether this cut is optional (candidate is accepted if any optional cut passes).
117+
void addSelection(int observableIndex,
118+
std::string const& selectionName,
119+
std::vector<std::string> const& selectionRanges,
120+
bool skipMostPermissiveBit,
121+
bool isMinimalCut,
122+
bool isOptionalCut)
123+
{
124+
// check index
125+
if (static_cast<std::size_t>(observableIndex) >= NumObservables) {
126+
LOG(fatal) << "Observable is not valid. Observable (index) has to be smaller than " << NumObservables;
144127
}
128+
// init selection container for selection at given index
129+
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, selectionRanges, skipMostPermissiveBit, isMinimalCut, isOptionalCut);
130+
131+
init(observableIndex);
145132
}
146133

147134
/// \brief Add a boolean-based selection for a specific observable.
@@ -158,32 +145,17 @@ class BaseSelection
158145
switch (mode) {
159146
case -1: // cut is optional and we store a bit for it
160147
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, std::vector<T>{1}, limits::LimitType::kEqual, false, false, true);
161-
mHasOptionalSelection = true;
162-
mNSelectionBits += 1;
163-
mNSelection += 1;
164148
break;
165149
case 0: // cut is disabled; initialize with empty vector so evaluation bails out early
166150
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, std::vector<T>{}, limits::LimitType::kEqual, false, false, false);
167151
break;
168152
case 1: // mandatory cut; only one threshold so the most permissive bit is skipped and no extra bit is stored
169153
mSelectionContainers.at(observableIndex) = SelectionContainer<T, BitmaskType>(selectionName, std::vector<T>{1}, limits::LimitType::kEqual, true, true, false);
170-
mHasMinimalSelection = true;
171-
mNSelection += 1;
172154
break;
173155
default:
174156
LOG(fatal) << "Invalid switch for boolean selection";
175157
}
176-
177-
if (mSelectionContainers.at(observableIndex).isMinimalCut()) {
178-
mHasMinimalSelection = true;
179-
}
180-
if (mSelectionContainers.at(observableIndex).isOptionalCut()) {
181-
mHasOptionalSelection = true;
182-
}
183-
184-
if (mNSelectionBits > sizeof(BitmaskType) * CHAR_BIT) {
185-
LOG(fatal) << "Too many selections. At most " << sizeof(BitmaskType) * CHAR_BIT << " are supported";
186-
}
158+
init(observableIndex);
187159
}
188160

189161
/// \brief Update the limits of a function-based selection for a specific observable.
@@ -371,7 +343,7 @@ class BaseSelection
371343
{
372344
LOG(info) << "Printing Configuration of " << objectName;
373345
for (size_t idx = 0; idx < mSelectionContainers.size(); ++idx) {
374-
const auto& container = mSelectionContainers[idx];
346+
const auto& container = mSelectionContainers.at(idx);
375347
if (container.isEmpty()) {
376348
continue;
377349
}
@@ -385,15 +357,11 @@ class BaseSelection
385357
LOG(info) << " Bitmask shift : " << container.getShift();
386358
LOG(info) << " Selections:";
387359

388-
const bool useFunctions = container.isUsingFunctions();
389-
const auto& values = container.getSelectionValues();
390-
const auto& functions = container.getSelectionFunction();
391-
const auto& comments = container.getComments();
392-
393360
for (std::size_t j = 0; j < container.getNSelections(); ++j) {
394361

395362
std::stringstream line;
396-
std::string sel = useFunctions ? std::string(functions[j].GetExpFormula().Data()) : std::to_string(values[j]);
363+
std::string sel = container.getValueAsString(j);
364+
std::string comment = container.getComment(j);
397365

398366
line << " " << std::left << std::setw(25) << sel;
399367

@@ -404,8 +372,8 @@ class BaseSelection
404372
line << "-> Bit: 0x" << std::hex << std::uppercase << (1ULL << bit) << std::dec;
405373
}
406374

407-
if (!comments.empty()) {
408-
line << " (" << comments.at(j) << ")";
375+
if (!comment.empty()) {
376+
line << " (" << comment << ")";
409377
}
410378
LOG(info) << line.str();
411379
}
@@ -446,6 +414,31 @@ class BaseSelection
446414
}
447415

448416
protected:
417+
void init(int observableIndex)
418+
{
419+
// check if any selections are configured
420+
if (mSelectionContainers.at(observableIndex).isEmpty()) {
421+
return;
422+
}
423+
424+
// track the number of occupied bits and total selections
425+
mNSelectionBits += mSelectionContainers.at(observableIndex).getShift();
426+
mNSelection += mSelectionContainers.at(observableIndex).getNSelections();
427+
428+
// check if any selection is minimal
429+
if (mSelectionContainers.at(observableIndex).isMinimalCut()) {
430+
mHasMinimalSelection = true;
431+
}
432+
// check if selection is optional
433+
if (mSelectionContainers.at(observableIndex).isOptionalCut()) {
434+
mHasOptionalSelection = true;
435+
}
436+
437+
if (mNSelectionBits > sizeof(BitmaskType) * CHAR_BIT) {
438+
LOG(fatal) << "Too many selections. At most " << sizeof(BitmaskType) * CHAR_BIT << " number of bits are supported";
439+
}
440+
}
441+
449442
o2::framework::HistogramRegistry* mHistRegistry = nullptr;
450443
std::array<SelectionContainer<T, BitmaskType>, NumObservables> mSelectionContainers = {}; ///< Array of selection containers, one per observable
451444
std::bitset<sizeof(BitmaskType) * CHAR_BIT> mFinalBitmask = {}; ///< Assembled bitmask combining all observable selections

0 commit comments

Comments
 (0)