2121#include " fairlogger/Logger.h"
2222
2323#include < algorithm>
24+ #include < iomanip>
2425#include < string>
2526#include < vector>
2627
@@ -54,6 +55,10 @@ class BaseSelection
5455 if (mNSelections >= sizeof (BitmaskType) * CHAR_BIT ) {
5556 LOG (fatal) << " Too many selections. At most " << sizeof (BitmaskType) * CHAR_BIT << " are supported" ;
5657 }
58+ // check if any cut is optional
59+ if (!isMinimalCut) {
60+ mHasOptionalCuts = true ;
61+ }
5762 mSelectionContainers .at (observableIndex) = SelectionContainer<T, BitmaskType>(selectionValues, limitType, skipMostPermissiveBit, isMinimalCut);
5863 }
5964
@@ -79,7 +84,9 @@ class BaseSelection
7984 {
8085 mFinalBitmask .reset ();
8186 mPassesMinimalCuts = true ;
82- mPassesOptionalCuts = false ;
87+ // will be true if no optional cut as been defined and
88+ // 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 ;
8390 }
8491
8592 // / set bitmask for a given observable
@@ -140,16 +147,77 @@ class BaseSelection
140147 }
141148 }
142149
143- BitmaskType getBitmask () const { return static_cast <BitmaskType>(mFinalBitmask .to_ulong ()); }
150+ BitmaskType getBitmask () const { return static_cast <BitmaskType>(mFinalBitmask .to_ullong ()); }
151+
152+ #include < iomanip> // for setw, left
153+ #include < sstream>
154+
155+ template <typename MapType>
156+ void printSelections (const std::string& objectName, const std::unordered_map<MapType, std::string>& observableNames) const
157+ {
158+ LOG (info) << " **************************************** FemtoProducer ****************************************" ;
159+ LOG (info) << objectName << " \n " ;
160+
161+ size_t globalBitIndex = 0 ; // Track absolute bit position across all containers
162+
163+ for (size_t idx = mSelectionContainers .size (); idx-- > 0 ;) {
164+ const auto & container = mSelectionContainers [idx];
165+ if (container.isEmpty ()) {
166+ continue ;
167+ }
168+
169+ std::string name = " [Unknown]" ;
170+ auto key = static_cast <MapType>(idx);
171+ if (observableNames.count (key)) {
172+ name = observableNames.at (key);
173+ }
174+
175+ LOG (info) << " Observable: " << name << " (index " << idx << " )" ;
176+ LOG (info) << " Limit type : " << container.getLimitTypeAsString ();
177+ LOG (info) << " Values (with bit indices and bitmask):" ;
178+
179+ const auto & values = container.getSelectionValues ();
180+ bool skipMostPermissive = container.skipMostPermissiveBit ();
181+
182+ constexpr int valWidth = 15 ;
183+ constexpr int bitWidth = 20 ;
184+ constexpr int maskWidth = 12 ;
185+
186+ for (size_t j = 0 ; j < values.size (); ++j) {
187+ std::stringstream line;
188+ line << " "
189+ << std::left << std::setw (valWidth) << values[j];
190+
191+ if (skipMostPermissive && j == 0 ) {
192+ line << std::setw (bitWidth) << " [no bit (skipped)]"
193+ << std::setw (maskWidth) << " " ;
194+ } else {
195+ uint64_t bitmask = uint64_t {1 } << globalBitIndex;
196+ line << std::setw (bitWidth) << (" [bit " + std::to_string (globalBitIndex) + " ]" )
197+ << " bitmask: " << bitmask;
198+ ++globalBitIndex;
199+ }
200+
201+ LOG (info) << line.str ();
202+ }
203+
204+ LOG (info) << " Minimal cut : " << (container.isMinimalCut () ? " yes" : " no" );
205+ LOG (info) << " Skip most permissive : " << (skipMostPermissive ? " yes" : " no" );
206+ LOG (info) << " Bitmask shift : " << container.getShift ();
207+ LOG (info) << " " ; // blank line between observables
208+ }
209+
210+ LOG (info) << " ***********************************************************************************************" ;
211+ }
144212
145213 protected:
146- std::array<SelectionContainer<T, BitmaskType>, NumObservables> mSelectionContainers ; // /< Array containing all selections
147- std::bitset<sizeof (BitmaskType) * CHAR_BIT > mFinalBitmask ; // /< final bitmaks
148- size_t mNSelections = 0 ; // /< Number of selections
149- bool mPassesMinimalCuts = true ; // /< Set to true if all minimal (mandatory) cuts are passed
150- bool mPassesOptionalCuts = false ; // /< Set to true if at least one optional (non-mandatory) cut is passed
214+ std::array<SelectionContainer<T, BitmaskType>, NumObservables> mSelectionContainers = {}; // /< Array containing all selections
215+ std::bitset<sizeof (BitmaskType) * CHAR_BIT > mFinalBitmask = {}; // /< final bitmaks
216+ 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
151220};
152-
153221} // namespace o2::analysis::femtounited
154222
155223#endif // PWGCF_FEMTOUNITED_CORE_BASESELECTION_H_
0 commit comments