ATLAS Offline Software
CaloGPUClusterAndCellDataMonitorOptions.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
7 #ifndef CALORECGPU_CALOGPUCLUSTERANDCELLDATAMONITOROPTIONS_H
8 #define CALORECGPU_CALOGPUCLUSTERANDCELLDATAMONITOROPTIONS_H
9 
10 //This sets up some classes to be usable as options within Gaudi (and thus Athena),
11 //so that we can more ergonomically specify our plotter's options.
12 //
13 //For reference, see Gaudi/GaudiExamples/src/Properties/CustomPropertiesAlg.cpp
14 
15 
16 #include <tuple>
17 #include <iostream>
18 #include <string>
19 #include <type_traits>
20 
21 
22 
24 
25 #include "GaudiKernel/StatusCode.h"
26 
27 #include <Gaudi/Parsers/Factory.h>
28 
29 //Suppress the warning that comes up from simply including Factory.h.
30 
31 //First, generic handling of tuples.
32 //This does set us up for handling more than we strictly need,
33 //but since this is only a local include
34 //and shouldn't bleed over to other parts of the code,
35 //we'll behave and (hopefully) not do anything too crazy.
36 
37 
38 //Since we're at C++17 level,
39 //we'll use SFINAE and enable_if
40 //to provide the *actual* parse and grammar and output
41 //that are necessary for custom types for Gaudi options.
42 //In C++20, of course we could use concepts
43 //for a more elegant implementation...
44 
45 namespace impl
46 {
47  template <class Check> struct class_can_be_tuple
48  {
49  template<class T> inline static constexpr
50  auto tuple_type_checker(T *) -> decltype(typename T::TupleType {});
51  template<class T> inline static constexpr
52  void tuple_type_checker(...);
53  template <class T> using tuple_type_checker_type = decltype( tuple_type_checker<T>(nullptr) );
54  template <class T> inline static constexpr
55  bool tuple_type_exists = !std::is_same_v<tuple_type_checker_type<T>, void>;
56 
57  template<class T> inline static constexpr
58  auto to_tuple_checker(T *) -> decltype(&T::to_tuple);
59  template<class T> inline static constexpr
60  void to_tuple_checker(...);
61  template <class T> inline static constexpr
62  bool to_tuple_exists = std::is_pointer_v<decltype( to_tuple_checker<T>(nullptr) )>;
63 
64  template<class T> inline static constexpr
65  auto from_tuple_checker(T *) -> decltype(&T::from_tuple);
66  template<class T> inline static constexpr
67  void from_tuple_checker(...);
68  template <class T> inline static constexpr
69  bool from_tuple_exists = std::is_pointer_v<decltype( from_tuple_checker<T>(nullptr) )>;
70 
71  template<class T> inline static constexpr
72  auto tuple_size_checker(T *) -> decltype(T::TupleSize);
73  template<class T> inline static constexpr
74  void tuple_size_checker(...);
75  template <class T> inline static constexpr
76  bool tuple_size_exists = !std::is_void_v<decltype(tuple_size_checker<T>(nullptr))>;
77 
78  inline constexpr static bool value = tuple_type_exists<Check> && to_tuple_exists<Check> && from_tuple_exists<Check> && tuple_size_exists<Check>;
79  };
80 
81  template <class T>
82  inline static constexpr bool class_can_be_tuple_v = class_can_be_tuple<T>::value;
83 
84  template <class T>
85  void tuple_safe_copy(T & dest, const T & source)
86  {
87  dest = source;
88  }
89 }
90 
91 //We use our macros to write a relatively limited form of variadic structured bindings
92 //for the tuple <-> struct conversions.
93 
94 #include "MacroHelpers.h"
95 
96 #define CALORECGPU_VARSB_APPENDER(THIS, PREFIX, IGNORE) , CRGPU_CONCAT(PREFIX, THIS)
97 #define CALORECGPU_VARSB_ASSIGNER(THIS, IGNORE1, IGNORE2) tuple_safe_copy(CRGPU_CONCAT(b, THIS), CRGPU_CONCAT(a, THIS));
98 
99 #define CALORECGPU_VARSB_ENCAPSULATOR_A(...) CRGPU_MACRO_EXPANSION(CALORECGPU_VARSB_APPENDER, a, __VA_ARGS__ )
100 #define CALORECGPU_VARSB_ENCAPSULATOR_B(...) CRGPU_MACRO_EXPANSION(CALORECGPU_VARSB_APPENDER, b, __VA_ARGS__ )
101 
102 #define CALORECGPU_VARSB_ENCAPSULATOR_ASSIGN(...) CRGPU_MACRO_EXPANSION(CALORECGPU_VARSB_ASSIGNER, _ , __VA_ARGS__, )
103 
104 
105 #define CALORECGPU_VARSB_EXPANDER(THIS_NUM, IGNORE, SMALLER_NUMS) \
106  template <> struct struct_tuple_conversion<THIS_NUM> \
107  { \
108  template <class T, class TupleT> \
109  static void s2t(const T & t, TupleT & tup) \
110  { \
111  const auto & [CRGPU_CONCAT(a, THIS_NUM) CALORECGPU_VARSB_ENCAPSULATOR_A SMALLER_NUMS] = t; \
112  auto & [CRGPU_CONCAT(b, THIS_NUM) CALORECGPU_VARSB_ENCAPSULATOR_B SMALLER_NUMS] = tup; \
113  tuple_safe_copy(CRGPU_CONCAT(b, THIS_NUM), CRGPU_CONCAT(a, THIS_NUM)); \
114  CALORECGPU_VARSB_ENCAPSULATOR_ASSIGN SMALLER_NUMS \
115  } \
116  template <class TupleT, class T> \
117  static void t2s(const TupleT & tup, T & t) \
118  { \
119  const auto & [CRGPU_CONCAT(a, THIS_NUM) CALORECGPU_VARSB_ENCAPSULATOR_A SMALLER_NUMS] = tup; \
120  auto & [CRGPU_CONCAT(b, THIS_NUM) CALORECGPU_VARSB_ENCAPSULATOR_B SMALLER_NUMS] = t; \
121  tuple_safe_copy(CRGPU_CONCAT(b, THIS_NUM), CRGPU_CONCAT(a, THIS_NUM)); \
122  CALORECGPU_VARSB_ENCAPSULATOR_ASSIGN SMALLER_NUMS \
123  } \
124  }; \
125 
126 //If only there were truly variadic structured bindings...
127 
128 namespace impl
129 {
130 
131  template <size_t n> struct struct_tuple_conversion
132  {
133  template <class T, class TupleT>
134  static void s2t(const T &, TupleT &) { }
135  template <class T, class TupleT>
136  static T t2s(const TupleT &, T &) { }
137  };
138 
140  //If we needed structs with more than 9 elements, just add more numbers to the left in descending order...
141 
142  template <class T,
143  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
144  void tuple_safe_copy(T & s, const typename T::TupleType & tuple)
145  {
147  }
148 
149  template <class T,
150  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
151  void tuple_safe_copy(typename T::TupleType & tuple, const T & s)
152  {
154  }
155 
156  template <class T,
157  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
158  void tuple_safe_copy(std::vector<typename T::TupleType> & t_v, const std::vector<T> & s_v)
159  {
160  t_v.resize(s_v.size());
161  for (size_t i = 0; i < s_v.size(); ++i)
162  {
163  tuple_safe_copy(t_v[i], s_v[i]);
164  }
165  }
166 
167  template <class T,
168  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
169  void tuple_safe_copy(std::vector<T> & s_v, const std::vector<typename T::TupleType> & t_v)
170  {
171  s_v.resize(t_v.size());
172  for (size_t i = 0; i < t_v.size(); ++i)
173  {
174  tuple_safe_copy(s_v[i], t_v[i]);
175  }
176  }
177 
178 
179  template <class T>
180  auto to_tuple_type_helper(const T &)
181  {
182  return T{};
183  }
184  /*
185  template <class T,
186  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
187  auto to_tuple_type_helper(const T&)
188  {
189  return typename T::TupleType{};
190  }
191  */
192  template <class T,
193  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
194  auto to_tuple_type_helper(const std::vector<T> &)
195  {
196  return std::vector<typename T::TupleType> {};
197  }
198 
199  /*
200  template <class ... Elems>
201  auto to_tuple_type_helper(const std::tuple<Elems...> &)
202  {
203  return std::tuple<decltype(to_tuple_type_helper(std::declval<Elems>))...>{};
204  }
205  */
206  //More specializations if needed?
207 
208 
209  template <class T>
210  using to_tuple_type = decltype(to_tuple_type_helper(std::declval<T>()));
211 
212  template <class T, class ... Elems> struct simple_tuple_conversion
213  {
214  using TupleType = std::tuple<to_tuple_type<Elems>...>;
215 
216  inline static constexpr size_t TupleSize = sizeof...(Elems);
217 
218  static TupleType to_tuple (const T & s)
219  {
220  TupleType ret;
222  return ret;
223  }
224  static T from_tuple(const TupleType & tup)
225  {
226  T ret;
228  return ret;
229  }
230  /*
231  friend
232  std::ostream & operator<< (std::ostream & s, const T & t)
233  {
234  return s << to_tuple(t);
235  }
236  */
237  };
238 
239  //If we had reflection, this would be so much easier...
240 
241  template <class Stream, class T>
242  void output_helper(Stream & s, const T & t, const std::string & after)
243  {
245  s << after;
246  }
247 
248  template <class Stream, class T>
249  void output_helper(Stream & s, const std::vector<T> & v, const std::string & after)
250  {
251  s << "[";
252  for (size_t i = 0; i < v.size(); ++i)
253  {
254  if (i > 0)
255  {
256  s << ", ";
257  }
258  impl::output_helper(s, v[i], "");
259  }
260  s << "]" << after;
261  }
262  /*
263  template <class Stream, class T,
264  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
265  void output_helper(Stream & s, const T & t, const std::string & after)
266  {
267  s << t << after;
268  }
269  */
270 }
271 
272 namespace Gaudi
273 {
274  namespace Parsers
275  {
276 
277  template <typename Iterator, typename Skipper, class T>
278  struct Grammar_< Iterator, T, Skipper, typename std::enable_if_t < impl::class_can_be_tuple_v<T> > >
279  {
280  using Grammar = typename Grammar_<Iterator, typename T::TupleType, Skipper>::Grammar;
281  };
282 
283  template <class ... Tup>
284  StatusCode parse(std::tuple<Tup...> & tup, const Gaudi::Parsers::InputData & input)
285  {
286  return parse_(tup, input);
287  }
288 
289  template <class T>
290  StatusCode parse(std::vector<T> & v, const Gaudi::Parsers::InputData & input)
291  {
292  return parse_(v, input);
293  }
294 
295  }
296 }
297 
298 template <class ... Tup>
299 std::ostream & operator<<(std::ostream & s, const std::tuple<Tup...> & tup )
300 {
301  std::apply( [&] (const Tup & ... arg)
302  {
303  s << "(";
304 
305  size_t num = 0;
306 
307  (void) ( (void) impl::output_helper(s, arg, (++num < sizeof...(Tup) ? ", " : "")), ... );
308 
309  s << ")";
310 
311  }, tup );
312 
313  return s;
314 }
315 
316 template < class T,
317  std::enable_if_t< impl::class_can_be_tuple_v<T>>* = nullptr>
318 std::ostream & operator<<(std::ostream & s, const T & t )
319 {
320  return s << T::to_tuple(t);
321 }
322 
323 //And now for the classes proper.
324 //
325 //In general:
326 //
327 //struct ClassName: impl::simple_tuple_conversion<ClassName, T1, T2, ... , TN>
328 //{
329 // T1 name1;
330 // T2 name2;
331 // ...
332 // TN nameN;
333 //
334 // ClassName() = default;
335 // ClassName(const TupleType & t)
336 // {
337 // (*this) = from_tuple(t);
338 // }
339 //};
340 //
341 //One could use the helper macro below.
342 //
343 //If there are mismatches in the types on the simple_tuple_conversion list,
344 //ugly compilation issues may ensue!
345 
346 #define CALORECGPU_OPTIONCLASS_CONSTRUCTORS(CLASSNAME) \
347  CLASSNAME() = default; \
348  CLASSNAME(const TupleType & t) \
349  { \
350  (*this) = from_tuple(t); \
351  } \
352 
354  impl::simple_tuple_conversion<MatchingOptions, double, double, double, double>
355 {
356  double min_similarity = 0.50, term_w = 250., grow_w = 500., seed_w = 1000.;
357 
359 };
360 
362  impl::simple_tuple_conversion<SimpleSingleTool, std::string, std::string>
363 {
364  std::string tool, plot_id;
365 
367 };
368 
370  impl::simple_tuple_conversion<SimpleToolPair, std::string, std::string, std::string, bool, bool, bool>
371 {
372  std::string tool_ref, tool_test, plot_id;
373  bool match_in_energy = false;
374  bool match_without_shared = false;
375  bool match_perfectly = false;
376 
378 };
379 
380 //This was used more heavily when we had the standalone plotter,
381 //but I would like to keep it here in case more changes are necessary...
382 
383 #endif //CALORECGPU_CALOGPUCLUSTERANDCELLDATAMONITOROPTIONS_H
SimpleToolPair::match_perfectly
bool match_perfectly
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:375
impl::class_can_be_tuple::from_tuple_checker
static constexpr void from_tuple_checker(...)
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Gaudi::Parsers::Grammar_< Iterator, T, Skipper, typename std::enable_if_t< impl::class_can_be_tuple_v< T > > >::Grammar
typename Grammar_< Iterator, typename T::TupleType, Skipper >::Grammar Grammar
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:280
Gaudi::Parsers::parse
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:284
Run3DQTestingDriver._
_
Definition: Run3DQTestingDriver.py:35
MatchingOptions::seed_w
double seed_w
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:356
Gaudi::Utils::toStream
std::ostream & toStream(const SG::VarHandleKeyArray &v, std::ostream &o)
Gaudi function used to convert a property to a string.
Definition: StoreGate/src/VarHandleKeyArray.cxx:47
impl::simple_tuple_conversion< SimpleSingleTool, std::string, std::string >::TupleType
std::tuple< to_tuple_type< Elems >... > TupleType
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:214
impl::class_can_be_tuple::to_tuple_checker
static constexpr auto to_tuple_checker(T *) -> decltype(&T::to_tuple)
impl::simple_tuple_conversion
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:213
SimpleToolPair::match_in_energy
bool match_in_energy
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:373
impl::class_can_be_tuple::tuple_type_checker
static constexpr void tuple_type_checker(...)
sct_calib_tf.Stream
string Stream
Definition: sct_calib_tf.py:31
operator<<
std::ostream & operator<<(std::ostream &s, const std::tuple< Tup... > &tup)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:299
taskman.template
dictionary template
Definition: taskman.py:317
MatchingOptions::term_w
double term_w
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:356
MatchingOptions::min_similarity
double min_similarity
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:356
perfmonmt-printer.dest
dest
Definition: perfmonmt-printer.py:189
SimpleToolPair::tool_test
std::string tool_test
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:372
impl::class_can_be_tuple::tuple_size_exists
static constexpr bool tuple_size_exists
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:76
CALORECGPU_OPTIONCLASS_CONSTRUCTORS
#define CALORECGPU_OPTIONCLASS_CONSTRUCTORS(CLASSNAME)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:346
impl::simple_tuple_conversion::TupleSize
static constexpr size_t TupleSize
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:216
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
CRGPU_MACRO_EXPANSION
#define CRGPU_MACRO_EXPANSION(MACRO, EXTRA_ARG,...)
Helper macro to apply a macro to all elements of the variadic list, with EXTRA_ARG and the parenthesi...
Definition: MacroHelpers.h:94
impl::class_can_be_tuple::tuple_type_exists
static constexpr bool tuple_type_exists
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:55
impl::struct_tuple_conversion
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:132
SimpleSingleTool::plot_id
std::string plot_id
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:364
impl::class_can_be_tuple::tuple_size_checker
static constexpr void tuple_size_checker(...)
lumiFormat.i
int i
Definition: lumiFormat.py:85
impl::class_can_be_tuple::value
constexpr static bool value
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:78
SimpleSingleTool::tool
std::string tool
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:364
CRGPU_RECURSIVE_MACRO
#define CRGPU_RECURSIVE_MACRO(...)
Expands recursive macros.
Definition: MacroHelpers.h:68
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
AthAlgTool.h
impl::class_can_be_tuple::tuple_type_checker
static constexpr auto tuple_type_checker(T *) -> decltype(typename T::TupleType
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:50
impl::to_tuple_type
decltype(to_tuple_type_helper(std::declval< T >())) to_tuple_type
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:210
MacroHelpers.h
CALORECGPU_VARSB_EXPANDER
#define CALORECGPU_VARSB_EXPANDER(THIS_NUM, IGNORE, SMALLER_NUMS)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:105
impl::class_can_be_tuple::to_tuple_exists
static constexpr bool to_tuple_exists
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:62
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
impl::simple_tuple_conversion::from_tuple
static T from_tuple(const TupleType &tup)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:224
SimpleToolPair
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:371
SimpleToolPair::tool_ref
std::string tool_ref
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:372
impl::to_tuple_type_helper
auto to_tuple_type_helper(const T &)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:180
SimpleToolPair::match_without_shared
bool match_without_shared
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:374
python.Dumpers.typename
def typename(t)
Definition: Dumpers.py:194
impl::class_can_be_tuple::from_tuple_checker
static constexpr auto from_tuple_checker(T *) -> decltype(&T::from_tuple)
impl::class_can_be_tuple::tuple_size_checker
static constexpr auto tuple_size_checker(T *) -> decltype(T::TupleSize)
python.PyAthena.v
v
Definition: PyAthena.py:154
MatchingOptions
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:355
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
impl::class_can_be_tuple::tuple_type_checker_type
decltype(tuple_type_checker< T >(nullptr)) tuple_type_checker_type
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:53
impl::class_can_be_tuple::to_tuple_checker
static constexpr void to_tuple_checker(...)
impl::class_can_be_tuple::from_tuple_exists
static constexpr bool from_tuple_exists
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:69
SimpleSingleTool
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:363
impl::simple_tuple_conversion::to_tuple
static TupleType to_tuple(const T &s)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:218
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
copySelective.source
string source
Definition: copySelective.py:32
SimpleToolPair::plot_id
std::string plot_id
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:372
impl::struct_tuple_conversion::t2s
static T t2s(const TupleT &, T &)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:136
impl::class_can_be_tuple
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:48
python.dqu_subprocess.apply
def apply(func, args)
Definition: dqu_subprocess.py:11
impl::tuple_safe_copy
void tuple_safe_copy(T &dest, const T &source)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:85
impl::output_helper
void output_helper(Stream &s, const T &t, const std::string &after)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:242
impl::struct_tuple_conversion::s2t
static void s2t(const T &, TupleT &)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:134
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
MatchingOptions::grow_w
double grow_w
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:356