Skip to content

Commit 0d596a8

Browse files
authored
[PWGCF] Add exclusion ranges to femto framework (#18422)
1 parent 2ced90d commit 0d596a8

4 files changed

Lines changed: 274 additions & 167 deletions

File tree

‎PWGCF/Femto/Core/baseSelection.h‎

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,24 @@ class BaseSelection
125125
addSelection(observableIndex);
126126
}
127127

128-
/// \brief Add a static-value based selection for a specific observable.
128+
/// \brief Add a range-based selection (either inside or outside the configured ranges) for a
129+
/// specific observable.
129130
/// \param observableIndex Index of the observable.
130131
/// \param selectionName Name of the selection.
131-
/// \param selectionValues Vector of threshold values.
132-
/// \param limitType Type of limit (from limits::LimitType).
132+
/// \param selectionRanges Vector of "lower;upper" range strings.
133133
/// \param skipMostPermissiveBit Whether to skip the loosest threshold when assembling the bitmask.
134134
/// \param isMinimalCut Whether this cut is mandatory (must be passed for the candidate to be accepted).
135135
/// \param isOptionalCut Whether this cut is optional (candidate is accepted if any optional cut passes).
136+
/// \param limitType Either limits::kInsideRange (value must fall inside) or limits::kOutsideRange
137+
/// (value must fall outside, e.g. rejecting a competing mass hypothesis). A
138+
/// fully-open range entry (";") is exempt for either type -- see SelectionContainer.
136139
void addSelection(int observableIndex,
137140
std::string const& selectionName,
138141
std::vector<std::string> const& selectionRanges,
139142
bool skipMostPermissiveBit,
140143
bool isMinimalCut,
141-
bool isOptionalCut)
144+
bool isOptionalCut,
145+
limits::LimitType limitType = limits::kInsideRange)
142146
{
143147
// check index
144148
if (static_cast<std::size_t>(observableIndex) >= NumObservables) {
@@ -149,7 +153,8 @@ class BaseSelection
149153
selectionRanges,
150154
mPassThrough ? false : skipMostPermissiveBit,
151155
mPassThrough ? false : isMinimalCut,
152-
mPassThrough ? false : isOptionalCut);
156+
mPassThrough ? false : isOptionalCut,
157+
limitType);
153158

154159
addSelection(observableIndex);
155160
}
@@ -248,6 +253,42 @@ class BaseSelection
248253
}
249254
}
250255

256+
/// \brief Evaluate the same observable for two independently-computed values of the same
257+
/// candidate and store only the logical AND of the two resulting per-threshold bitmasks
258+
/// \param observableIndex Index of the observable.
259+
/// \param value1 First value to evaluate.
260+
/// \param value2 Second value to evaluate.
261+
void evaluateObservable(int observableIndex, T value1, T value2)
262+
{
263+
// if there are no selections configured, bail out
264+
if (mSelectionContainers.at(observableIndex).isEmpty()) {
265+
return;
266+
}
267+
// if a previous observable already failed a minimal selection,
268+
// there is no point in evaluating further observables
269+
if (!mPassesMinimalSelections) {
270+
return;
271+
}
272+
auto& container = mSelectionContainers.at(observableIndex);
273+
container.evaluate(value1);
274+
auto const bitmask1 = container.getRawBitmask();
275+
container.evaluate(value2);
276+
auto const bitmask2 = container.getRawBitmask();
277+
container.setBitmask((bitmask1 & bitmask2).to_ullong());
278+
// if any minimal selection is not fulfilled, the candidate is rejected
279+
if (mHasMinimalSelection) {
280+
if (!container.passesAsMinimalCut()) {
281+
mPassesMinimalSelections = false;
282+
}
283+
}
284+
// if any optional selection is fulfilled, the candidate is accepted
285+
if (mHasOptionalSelection) {
286+
if (container.passesAsOptionalCut()) {
287+
mPassesOptionalSelections = true;
288+
}
289+
}
290+
}
291+
251292
/// \brief Evaluate a single observable against its configured selections.
252293
/// \param observableIndex Index of the observable.
253294
/// \param values Vector of values of the observable.

0 commit comments

Comments
 (0)