1- // Copyright 2019-2022 CERN and copyright holders of ALICE O2.
1+ // Copyright 2019-2025 CERN and copyright holders of ALICE O2.
22// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
33// All rights not expressly granted are reserved.
44//
1010// or submit itself to any jurisdiction.
1111
1212// / \file baseSelection.h
13- // / \brief Definition of the BaseSelection class
13+ // / \brief Defines the BaseSelection class for managing and evaluating multiple selections over multiple observables.
1414// / \author Anton Riedel, TU München, anton.riedel@tum.de
1515
1616#ifndef PWGCF_FEMTOUNITED_CORE_BASESELECTION_H_
2323#include < algorithm>
2424#include < iomanip>
2525#include < string>
26+ #include < unordered_map>
2627#include < vector>
2728
2829namespace o2 ::analysis::femtounited
2930{
31+
3032// / \class BaseSelection
31- // / \brief Base class to contain all cuts and assemble bitmask
32- // / \tparam T Data type used for the selections (float/int/...)
33- // / \tparam BitmaskType Compute size of the bitmask from BitmaskType
34- // / \tparam NObservables Number of observables
33+ // / \brief Template class for managing selection criteria across multiple observables.
34+ // /
35+ // / This class manages an array of SelectionContainer objects, each corresponding to a specific observable.
36+ // / It evaluates which selections are fulfilled, assembles a final bitmask, and tracks required vs. optional cuts.
37+ // /
38+ // / \tparam T Type of observable values (mostly floats).
39+ // / \tparam BitmaskType Type used for internal bitmask operations (e.g., uint32_t, uint64_t).
40+ // / \tparam NumObservables Total number of observables handled.
3541template <typename T, typename BitmaskType, size_t NumObservables>
3642class BaseSelection
3743{
3844 public:
39- // / Constructor
45+ // / \brief Default constructor.
4046 BaseSelection () {}
4147
42- // / Destructor
48+ // / \brief Destructor
4349 virtual ~BaseSelection () = default ;
4450
45- // / Pass the Configurable of selection values in the analysis task to the selection class
46- // / \param configSelections Vector of configurables containing the values employed for the selection
47- // / \param Observable Observable to be employed for the selection
48- // / \param limitType Type of the selection limit
51+ // / \brief Add a static-value based selection for a specific observable.
52+ // / \param selectionValues Vector of threshold values.
53+ // / \param observableIndex Index of the observable.
54+ // / \param limitType Type of limit (from limits::LimitType).
55+ // / \param skipMostPermissiveBit Whether to skip the loosest threshold in the bitmask.
56+ // / \param isMinimalCut Whether this cut is mandatory or optional.
4957 void addSelection (std::vector<T> const & selectionValues, int observableIndex, limits::LimitType limitType, bool skipMostPermissiveBit, bool isMinimalCut)
5058 {
5159 if (static_cast <size_t >(observableIndex) >= NumObservables) {
@@ -57,15 +65,20 @@ class BaseSelection
5765 }
5866 // check if any cut is optional
5967 if (!isMinimalCut) {
60- mHasOptionalCuts = true ;
68+ mHasOptionalSelection = true ;
6169 }
6270 mSelectionContainers .at (observableIndex) = SelectionContainer<T, BitmaskType>(selectionValues, limitType, skipMostPermissiveBit, isMinimalCut);
6371 }
6472
65- // / Pass the Configurable of selection values in the analysis task to the selection class
66- // / \param configSelection Vector from configurable containing the values employed for the selection
67- // / \param observableType Observable to be employed for the selection
68- // / \param limitType Type of the selection limit
73+ // / \brief Add a function-based selection for a specific observable.
74+ // / \param baseName Base name for TF1 functions.
75+ // / \param lowerLimit Lower bound for the TF1 domain.
76+ // / \param upperLimit Upper bound for the TF1 domain.
77+ // / \param selectionValues Function definitions as strings.
78+ // / \param observableIndex Index of the observable.
79+ // / \param limitType Type of limit.
80+ // / \param skipMostPermissiveBit Whether to skip the loosest threshold in the bitmask.
81+ // / \param isMinimalCut Whether this cut is mandatory or optional.
6982 void addSelection (std::string const & baseName, T lowerLimit, T upperLimit, std::vector<std::string> const & selectionValues, int observableIndex, limits::LimitType limitType, bool skipMostPermissiveBit, bool isMinimalCut)
7083 {
7184 if (static_cast <size_t >(observableIndex) >= NumObservables) {
@@ -78,20 +91,24 @@ class BaseSelection
7891 mSelectionContainers .at (observableIndex) = SelectionContainer<T, BitmaskType>(baseName, lowerLimit, upperLimit, selectionValues, limitType, skipMostPermissiveBit, isMinimalCut);
7992 }
8093
94+ // / \brief Update the limits of a function-based selection for a specific observable.
95+ // / \param observable Index of the observable.
96+ // / \param value Value at which to evaluate the selection functions.
8197 void updateLimits (int observable, T value) { mSelectionContainers .at (observable).updateLimits (value); }
8298
99+ // / \brief Reset the internal bitmask and evaluation flags before evaluating a new event.
83100 void reset ()
84101 {
85102 mFinalBitmask .reset ();
86- mPassesMinimalCuts = true ;
103+ mPassesMinimalSelections = true ;
87104 // will be true if no optional cut as been defined and
88105 // will be set to false if we have optional cuts (but will be set to true in the case at least one optional cut succeeds)
89- mPassesOptionalCuts = !mHasOptionalCuts ;
106+ mPassesOptionalSelections = !mHasOptionalSelection ;
90107 }
91108
92- // / set bitmask for a given observable
93- // / \param observable Observable to be checked
94- // / \param value Value of the observable
109+ // / \brief Evaluate a single observable against its configured selections.
110+ // / \param observableIndex Index of the observable.
111+ // / \param value Value of the observable.
95112 void evaluateObservable (int observableIndex, T value)
96113 {
97114 // if there are no selections configured, bail out
@@ -100,37 +117,41 @@ class BaseSelection
100117 }
101118 // if any previous observable did not pass minimal selections, there is no point in setting bitmask for other observables
102119 // minimal selection for each observable is computed after adding it
103- if (mPassesMinimalCuts == false ) {
120+ if (mPassesMinimalSelections == false ) {
104121 return ;
105122 }
106123 // set bitmask for given observable
107124 mSelectionContainers .at (observableIndex).evaluate (value);
108125 // check if minimal selction for this observable holds
109126 if (mSelectionContainers .at (observableIndex).passesAsMinimalCut () == false ) {
110- mPassesMinimalCuts = false ;
127+ mPassesMinimalSelections = false ;
111128 }
112129 // check if any optional selection holds
113130 if (mSelectionContainers .at (observableIndex).passesAsOptionalCut () == true ) {
114- mPassesOptionalCuts = true ;
131+ mPassesOptionalSelections = true ;
115132 }
116133 }
117134
118- // / check if minimal Selections are passed
135+ // / \brief Check if all required (minimal) and optional cuts are passed.
136+ // / \return True if all required and at least one optional cut (if present) is passed.
119137 bool passesAllRequiredSelections () const
120138 {
121- return mPassesMinimalCuts && mPassesOptionalCuts ;
139+ return mPassesMinimalSelections && mPassesOptionalSelections ;
122140 }
123141
124- bool passesOptionalCut (int observableIndex) const
142+ // / \brief Check if the optional selection for a specific observable is passed.
143+ // / \param observableIndex Index of the observable.
144+ // / \return True if at least one optional selection is fulfilled.
145+ bool passesOptionalSelection (int observableIndex) const
125146 {
126147 return mSelectionContainers .at (observableIndex).passesAsOptionalCut ();
127148 }
128149
129- // / assemble final bitmask
150+ // / \brief Assemble the global selection bitmask from individual observable selections.
130151 void assembleBitmask ()
131152 {
132153 // if minimal selections are not passed, just set bitmask to 0
133- if (mPassesMinimalCuts == false ) {
154+ if (mPassesMinimalSelections == false ) {
134155 mFinalBitmask .reset ();
135156 return ;
136157 }
@@ -147,11 +168,15 @@ class BaseSelection
147168 }
148169 }
149170
171+ // / \brief Retrieve the assembled bitmask as an integer value.
172+ // / \return The combined selection bitmask.
150173 BitmaskType getBitmask () const { return static_cast <BitmaskType>(mFinalBitmask .to_ullong ()); }
151174
152- #include < iomanip> // for setw, left
153- #include < sstream>
154-
175+ // / \brief Print detailed information about all configured selections.
176+ // /
177+ // / \tparam MapType Type used in the observable name map (usually an enum or int).
178+ // / \param objectName Name of the current object (e.g. particle species).
179+ // / \param observableNames Map from observable index to human-readable names.
155180 template <typename MapType>
156181 void printSelections (const std::string& objectName, const std::unordered_map<MapType, std::string>& observableNames) const
157182 {
@@ -179,9 +204,9 @@ class BaseSelection
179204 const auto & values = container.getSelectionValues ();
180205 bool skipMostPermissive = container.skipMostPermissiveBit ();
181206
182- constexpr int valWidth = 15 ;
183- constexpr int bitWidth = 20 ;
184- constexpr int maskWidth = 12 ;
207+ int valWidth = 15 ;
208+ int bitWidth = 20 ;
209+ int maskWidth = 12 ;
185210
186211 for (size_t j = 0 ; j < values.size (); ++j) {
187212 std::stringstream line;
@@ -214,9 +239,9 @@ class BaseSelection
214239 std::array<SelectionContainer<T, BitmaskType>, NumObservables> mSelectionContainers = {}; // /< Array containing all selections
215240 std::bitset<sizeof (BitmaskType) * CHAR_BIT > mFinalBitmask = {}; // /< final bitmaks
216241 size_t mNSelections = 0 ; // /< Number of selections
217- bool mPassesMinimalCuts = true ; // /< Set to true if all minimal (mandatory) cuts are passed
218- bool mHasOptionalCuts = false ; // /< Set to true if at least one cut is optional
219- bool mPassesOptionalCuts = true ; // /< Set to true if at least one optional (non-mandatory) cut is passed
242+ bool mPassesMinimalSelections = true ; // /< Set to true if all minimal (mandatory) selections are passed
243+ bool mHasOptionalSelection = false ; // /< Set to true if at least one selections is optional
244+ bool mPassesOptionalSelections = true ; // /< Set to true if at least one optional (non-mandatory) selections is passed
220245};
221246} // namespace o2::analysis::femtounited
222247
0 commit comments