LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
GausFitCache.h
Go to the documentation of this file.
1 
12 #ifndef GAUSFITCACHE_H
13 #define GAUSFITCACHE_H 1
14 
15 // C/C++ standard libraries
16 #include <string>
17 #include <vector>
18 
19 // ROOT libraries
20 #include "RtypesCore.h" // Double_t
21 #include "TF1.h"
22 
23 namespace hit {
24 
45  class GausFitCache {
46  public:
48  GausFitCache(std::string new_name = "GausFitCache") : name(new_name) {}
49 
51  virtual ~GausFitCache();
52 
54  std::string GetName() const { return name; }
55 
67  virtual TF1* Get(size_t nFunc);
68 
71  virtual TF1* GetClone(size_t nGaus);
72 
74  virtual std::string FunctionName(size_t nFunc) const;
75 
76  protected:
77  std::string name;
78 
80  std::vector<TF1*> funcs;
81 
83  virtual TF1* CreateFunction(size_t nFunc) const;
84 
85  }; // class GausFitCache
86 
87  namespace details {
88 
89  template <typename T>
90  inline T sqr(T v)
91  {
92  return v * v;
93  }
94 
96  template <unsigned int NArg, typename FirstArg, typename... Args>
98  using type = typename TemplateArgumentHelper<NArg - 1, Args...>::type;
99  }; // struct TemplateArgumentHelper
100 
102  template <unsigned int NArg, typename... Args>
104  using type = typename TemplateArgumentHelper<NArg, Args...>::type;
105  }; // struct TemplateArgument
106 
121  template <unsigned int NFunc,
122  Double_t Func(Double_t const*, Double_t const*),
123  unsigned int NFuncParams>
124  struct FuncSum {
125  static Double_t eval(Double_t const*, Double_t const*);
126  static constexpr unsigned int NParams = NFunc * NFuncParams;
127  }; // struct FuncSum
128 
129  // partial specialization (declaration)
130  template <Double_t Func(Double_t const*, Double_t const*), unsigned int NFuncParams>
131  struct FuncSum<0U, Func, NFuncParams> {
132  static Double_t eval(Double_t const*, Double_t const*);
133  static constexpr unsigned int NParams = 0;
134  }; // struct FuncSum<0>
135 
137  /*
138  * Since, as most of C++ metaprogramming code, this one is quite messy,
139  * some explanations follow.
140  *
141  * The idea is to have a function sum of N base functions, and both N and
142  * which base function can be specified as template parameters.
143  *
144  * The implementation of the sum of N base functions requires a
145  * compile-time "for loop" that is implemented by recursion: a function
146  * with a template parameter N=i calls the same with N=i-1. The loop is
147  * interrupted by a template specialization for N=0 that does not call
148  * N=-1. Unfortunately there is another template parameter that is carried
149  * around, that is the base function. This means that the specialization
150  * for N=0 is a partial specialization, since the function still needs
151  * to be a template parameter. Partial specializations are only allowed
152  * for classes (not for functions). Therefore we have here a class
153  * with two template parameters and a static member eval() where the
154  * total function is defined. Partial specializations of the full class
155  * will implement the necessary N=0 exception to the recursion rule.
156  *
157  * Now, we want to put these in a vector of functions.
158  * This is another loop, and since the function types are decided at
159  * compile time, the loop must be done at compile time too.
160  * Here it goes another class, moving around a vector.
161  * Furthermore, now the actual type of function is a different one for
162  * each element in the array: in this compile-time for-loop, the type
163  * depends on the running parameter, and potentially on others.
164  *
165  *
166  *
167  *
168  */
169  public:
171 
173  virtual TF1* GetClone(size_t nGaus);
174 
176  virtual unsigned int MaxGaussians() const { return funcs.size() - 1; }
177 
186  static Double_t gaus(Double_t const* x, Double_t const* params);
187 
188  template <unsigned int CutOff>
189  static Double_t gaus_trunc(Double_t const* x, Double_t const* params);
190 
191  template <unsigned int NGaus>
192  static Double_t ngaus(Double_t const* x, Double_t const* params)
193  {
194  return gaus(x, params) + ngaus<NGaus - 1>(x, params + 3);
195  }
196 
198  template <unsigned int NGaus, unsigned int CutOff>
199  static Double_t ngaus_trunc(Double_t const* x, Double_t const* params)
200  {
201  return FuncSum<NGaus, gaus_trunc<CutOff>, 3U>::eval(x, params);
202  }
203 
205  template <unsigned int NGaus, unsigned int CutOff>
207 
208  protected:
227  template <unsigned int NFunc, template <unsigned int> class Func>
229  static void fill(CompiledGausFitCacheBaseStruct& cache);
230  }; // struct InitializeFuncSumVector
231 
232  // partial specialization: 0 of any function
233  template <template <unsigned int> class Func>
234  struct InitializeFuncSumVector<0U, Func> {
235  static void fill(CompiledGausFitCacheBaseStruct& cache);
236  }; // struct InitializeFuncSumVector<0, Func>
237 
239  template <unsigned int NGaus>
240  void InitializeCompiledGausFitVector();
241 
243  template <unsigned int NGaus>
244  void AppendFunction();
245 
247  void CannotCreateFunction [[noreturn]] (size_t nGaus) const;
248 
249  }; // class CompiledGausFitCacheBaseStruct
250 
251  } // namespace details
252 
260  template <unsigned int MaxGaus = 10>
262  public:
264  CompiledGausFitCache(std::string new_name = "CompiledGausFitCache")
265  : details::CompiledGausFitCacheBaseStruct(new_name)
266  {
267  InitializeCompiledGausFitVector<MaxGaus>();
268  }
269 
270  virtual unsigned int MaxGaussians() const { return StoredMaxGaussians(); }
271 
273  constexpr unsigned int StoredMaxGaussians() const { return MaxGaus; }
274 
275  protected:
277  virtual TF1* CreateFunction [[noreturn]] (size_t nGaus) const { CannotCreateFunction(nGaus); }
278 
279  }; // class CompiledGausFitCache
280 
290  template <unsigned int MaxGaus = 10, unsigned int CutOff = 5>
292  template <unsigned int NGaus>
294 
295  public:
297  CompiledTruncatedGausFitCache(std::string new_name = "CompiledTruncatedGausFitCache")
298  : details::CompiledGausFitCacheBaseStruct(new_name)
299  {
301  }
302 
303  virtual unsigned int MaxGaussians() const { return StoredMaxGaussians(); }
304 
306  constexpr unsigned int StoredMaxGaussians() const { return MaxGaus; }
307 
308  protected:
310  virtual TF1* CreateFunction [[noreturn]] (size_t nGaus) const { CannotCreateFunction(nGaus); }
311 
312  }; // class CompiledTruncatedGausFitCache
313 
314  //
315  // template implementation
316  //
317 
318  namespace details {
319 
320  // --- FuncSum -------------------------------------------------------------
321  template <unsigned int NFunc,
322  Double_t Func(Double_t const*, Double_t const*),
323  unsigned int NFuncParams>
324  constexpr unsigned int FuncSum<NFunc, Func, NFuncParams>::NParams;
325 
326  template <unsigned int NFunc,
327  Double_t Func(Double_t const*, Double_t const*),
328  unsigned int NFuncParams>
329  Double_t FuncSum<NFunc, Func, NFuncParams>::eval(Double_t const* x, Double_t const* params)
330  {
331  return Func(x, params + NFuncParams * (NFunc - 1)) // use the last parameters
333  } // CompiledGausFitCacheBaseStruct::FuncSum<NFunc, Func>::eval()
334 
335  // partial specialization: 0 of any function
336  template <Double_t Func(Double_t const*, Double_t const*), unsigned int NFuncParams>
337  Double_t FuncSum<0U, Func, NFuncParams>::eval(Double_t const*, Double_t const*)
338  {
339  return 0.;
340  }
341 
342  // --- CompiledGausFitCacheBaseStruct --------------------------------------
343 
344  template <unsigned int NGaus>
345  void CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector()
346  {
347  if (NGaus > 0) InitializeCompiledGausFitVector<NGaus - 1>();
348  AppendFunction<NGaus>();
349  } // CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector()
350 
351  template <>
352  inline void CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector<0>()
353  {
354  AppendFunction<0>();
355  }
356 
357  template <unsigned int NGaus>
358  void CompiledGausFitCacheBaseStruct::AppendFunction()
359  {
360  // create a function in the ficticious range [ 0, 1 ]:
361  funcs.push_back(new TF1(FunctionName(NGaus).c_str(), &ngaus<NGaus>, 0., 1., 3 * NGaus));
362  } // CompiledGausFitCacheBaseStruct::AppendFunction()
363 
364  template <unsigned int CutOff>
365  Double_t CompiledGausFitCacheBaseStruct::gaus_trunc(Double_t const* x, Double_t const* params)
366  {
367  const Double_t z = (x[0] - params[1]) / params[2];
368  return ((z > -((Double_t)CutOff)) && (z < (Double_t)CutOff)) ?
369  params[0] * std::exp(-0.5 * sqr(z)) :
370  0.;
371  } // CompiledGausFitCacheBaseStruct::gaus_trunc()
372 
373  template <>
374  inline Double_t CompiledGausFitCacheBaseStruct::ngaus<0>(Double_t const* /* x */,
375  Double_t const* /* params */)
376  {
377  return 0.;
378  }
379 
380  // --- CompiledGausFitCacheBaseStruct::InitializeFuncSumVector -------------
381 
382  template <unsigned int NFunc, template <unsigned int> class Func>
385  {
386  // first fill the lower functions
388  // then add one
389  cache.funcs.push_back(new TF1(
390  cache.FunctionName(NFunc).c_str(), Func<NFunc>::eval, 0., 1., Func<NFunc>::NParams));
391  } // InitializeFuncSumVector<NFunc, Func>::fill()
392 
393  template <template <unsigned int> class Func>
396  {
397  cache.funcs.push_back(new TF1(cache.FunctionName(0).c_str(), Func<0U>::eval, 0., 1., 0));
398  } // InitializeFuncSumVector<0, Func>::fill()
399 
400  // -------------------------------------------------------------------------
401 
402  } // namespace details
403 
404  // ---------------------------------------------------------------------------
405 
406 } // namespace hit
407 
408 #endif // GAUSFITCACHE_H
Float_t x
Definition: compare.C:6
virtual unsigned int MaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:270
constexpr unsigned int StoredMaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:306
std::vector< TF1 * > funcs
Definition: GausFitCache.h:80
virtual TF1 * CreateFunction(size_t nFunc) const
Creates a new sum function.
static Double_t ngaus_trunc(Double_t const *x, Double_t const *params)
Sum of NGaus Gaussian functions truncated at CutOff sigmas.
Definition: GausFitCache.h:199
Double_t z
Definition: plot.C:276
CompiledGausFitCache(std::string new_name="CompiledGausFitCache")
Constructor: initializes all the functions.
Definition: GausFitCache.h:264
A sum of NFunc base functions Func.
Definition: GausFitCache.h:124
A set of TF1 linear sum of base functions (Gaussians)
Definition: GausFitCache.h:45
virtual ~GausFitCache()
Destructor.
A set of TF1 linear sum of Gaussians.
Definition: GausFitCache.h:261
A set of TF1 linear sum of truncated Gaussians.
Definition: GausFitCache.h:291
A helper class initializing the function vector.
Definition: GausFitCache.h:228
virtual unsigned int MaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:176
Struct with member type corresponding to the NArg-th type from Args.
Definition: GausFitCache.h:97
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
virtual TF1 * Get(size_t nFunc)
Returns a function sum of nFunc base functions.
GausFitCache(std::string new_name="GausFitCache")
Constructor; optionally set the name of the repository.
Definition: GausFitCache.h:48
Detector simulation of raw signals on wires.
static Double_t ngaus(Double_t const *x, Double_t const *params)
Definition: GausFitCache.h:192
typename TemplateArgumentHelper< NArg-1, Args... >::type type
Definition: GausFitCache.h:98
constexpr unsigned int StoredMaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:273
CompiledTruncatedGausFitCache(std::string new_name="CompiledTruncatedGausFitCache")
Constructor: initializes all the functions.
Definition: GausFitCache.h:297
virtual std::string FunctionName(size_t nFunc) const
Returns a name for the function with nFunc base functions.
typename TemplateArgumentHelper< NArg, Args... >::type type
Definition: GausFitCache.h:104
virtual unsigned int MaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:303
std::string GetName() const
Return the name of this cache.
Definition: GausFitCache.h:54
Struct with member type corresponding to the NArg-th type from Args.
Definition: GausFitCache.h:103
std::string name
name of the cache
Definition: GausFitCache.h:77
virtual TF1 * GetClone(size_t nGaus)