LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
GausFitCache.h
Go to the documentation of this file.
1 
12 #ifndef GAUSFITCACHE_H
13 #define GAUSFITCACHE_H 1
14 
15 
16 // C/C++ standard libraries
17 #include <string>
18 #include <vector>
19 
20 // ROOT libraries
21 #include "Rtypes.h" // Double_t
22 #include "TF1.h" // Double_t
23 
24 // Framework libraries
26 
27 
28 namespace hit {
29 
50  class GausFitCache {
51  public:
53  GausFitCache(std::string new_name = "GausFitCache"): name(new_name) {}
54 
56  virtual ~GausFitCache();
57 
59  std::string GetName() const { return name; }
60 
72  virtual TF1* Get(size_t nFunc);
73 
76  virtual TF1* GetClone(size_t nGaus);
77 
79  virtual std::string FunctionName(size_t nFunc) const;
80 
81  protected:
82 
83  std::string name;
84 
86  std::vector<TF1*> funcs;
87 
89  virtual TF1* CreateFunction(size_t nFunc) const;
90 
91  }; // class GausFitCache
92 
93 
94 
95  namespace details {
96 
97  template <typename T>
98  inline T sqr(T v) { return v*v; }
99 
100 
102  template <unsigned int NArg, typename FirstArg, typename... Args>
104  using type = typename TemplateArgumentHelper<NArg - 1, Args...>::type;
105  }; // struct TemplateArgumentHelper
106 
107 
109  template <unsigned int NArg, typename... Args>
111  using type = typename TemplateArgumentHelper<NArg, Args...>::type;
112  }; // struct TemplateArgument
113 
114 
115 
130  template <
131  unsigned int NFunc,
132  Double_t Func(Double_t const*, Double_t const*),
133  unsigned int NFuncParams
134  >
135  struct FuncSum {
136  static Double_t eval(Double_t const*, Double_t const*);
137  static constexpr unsigned int NParams = NFunc * NFuncParams;
138  }; // struct FuncSum
139 
140  // partial specialization (declaration)
141  template <
142  Double_t Func(Double_t const*, Double_t const*),
143  unsigned int NFuncParams
144  >
145  struct FuncSum<0U, Func, NFuncParams>{
146  static Double_t eval(Double_t const*, Double_t const*);
147  static constexpr unsigned int NParams = 0;
148  }; // struct FuncSum<0>
149 
150 
151 
153  /*
154  * Since, as most of C++ metaprogramming code, this one is quite messy,
155  * some explanations follow.
156  *
157  * The idea is to have a function sum of N base functions, and both N and
158  * which base function can be specified as template parameters.
159  *
160  * The implementation of the sum of N base functions requires a
161  * compile-time "for loop" that is implemented by recursion: a function
162  * with a template parameter N=i calls the same with N=i-1. The loop is
163  * interrupted by a template specialization for N=0 that does not call
164  * N=-1. Unfortunately there is another template parameter that is carried
165  * around, that is the base function. This means that the specialization
166  * for N=0 is a partial specialization, since the function still needs
167  * to be a template parameter. Partial specializations are only allowed
168  * for classes (not for functions). Therefore we have here a class
169  * with two template parameters and a static member eval() where the
170  * total function is defined. Partial specializations of the full class
171  * will implement the necessary N=0 exception to the recursion rule.
172  *
173  * Now, we want to put these in a vector of functions.
174  * This is another loop, and since the function types are decided at
175  * compile time, the loop must be done at compile time too.
176  * Here it goes another class, moving around a vector.
177  * Furthermore, now the actual type of function is a different one for
178  * each element in the array: in this compile-time for-loop, the type
179  * depends on the running parameter, and potentially on others.
180  *
181  *
182  *
183  *
184  */
185  public:
187 
189  virtual TF1* GetClone(size_t nGaus);
190 
192  virtual unsigned int MaxGaussians() const { return funcs.size() - 1; }
193 
194 
203  static Double_t gaus(Double_t const* x, Double_t const* params);
204 
205  template <unsigned int CutOff>
206  static Double_t gaus_trunc(Double_t const* x, Double_t const* params);
207 
208 
209  template <unsigned int NGaus>
210  static Double_t ngaus(Double_t const* x, Double_t const* params)
211  { return gaus(x, params) + ngaus<NGaus-1>(x, params + 3); }
212 
213 
215  template <unsigned int NGaus, unsigned int CutOff>
216  static Double_t ngaus_trunc(Double_t const* x, Double_t const* params)
217  { return FuncSum<NGaus, gaus_trunc<CutOff>, 3U>::eval(x, params); }
218 
220  template <unsigned int NGaus, unsigned int CutOff>
222 
223 
224  protected:
225 
244  template <unsigned int NFunc, template <unsigned int> class Func>
246  static void fill(CompiledGausFitCacheBaseStruct& cache);
247  }; // struct InitializeFuncSumVector
248 
249  // partial specialization: 0 of any function
250  template <template <unsigned int> class Func>
251  struct InitializeFuncSumVector<0U, Func> {
252  static void fill(CompiledGausFitCacheBaseStruct& cache);
253  }; // struct InitializeFuncSumVector<0, Func>
254 
255 
257  template <unsigned int NGaus>
258  void InitializeCompiledGausFitVector();
259 
261  template <unsigned int NGaus>
262  void AppendFunction();
263 
265  void CannotCreateFunction [[noreturn]] (size_t nGaus) const;
266 
267  }; // class CompiledGausFitCacheBaseStruct
268 
269 
270  } // namespace details
271 
272 
280  template <unsigned int MaxGaus = 10>
282  {
283  public:
284 
286  CompiledGausFitCache(std::string new_name = "CompiledGausFitCache"):
287  details::CompiledGausFitCacheBaseStruct(new_name)
288  { InitializeCompiledGausFitVector<MaxGaus>(); }
289 
290  virtual unsigned int MaxGaussians() const { return StoredMaxGaussians(); }
291 
293  constexpr unsigned int StoredMaxGaussians() const { return MaxGaus; }
294 
295  protected:
296 
298  virtual TF1* CreateFunction [[noreturn]] (size_t nGaus) const
299  { CannotCreateFunction(nGaus); }
300 
301  }; // class CompiledGausFitCache
302 
303 
313  template <unsigned int MaxGaus = 10, unsigned int CutOff = 5>
316  {
317  template <unsigned int NGaus>
319 
320  public:
321 
324  (std::string new_name = "CompiledTruncatedGausFitCache"):
326  {
328  }
329 
330 
331  virtual unsigned int MaxGaussians() const { return StoredMaxGaussians(); }
332 
334  constexpr unsigned int StoredMaxGaussians() const { return MaxGaus; }
335 
336  protected:
337 
339  virtual TF1* CreateFunction [[noreturn]] (size_t nGaus) const
340  { CannotCreateFunction(nGaus); }
341 
342  }; // class CompiledTruncatedGausFitCache
343 
344 
345 
346  //
347  // template implementation
348  //
349 
350  namespace details {
351 
352  // --- FuncSum -------------------------------------------------------------
353  template <
354  unsigned int NFunc,
355  Double_t Func(Double_t const*, Double_t const*),
356  unsigned int NFuncParams
357  >
358  constexpr unsigned int FuncSum<NFunc, Func, NFuncParams>::NParams;
359 
360  template<
361  unsigned int NFunc,
362  Double_t Func(Double_t const*, Double_t const*),
363  unsigned int NFuncParams
364  >
365  Double_t FuncSum<NFunc, Func, NFuncParams>::eval
366  (Double_t const* x, Double_t const* params)
367  {
368  return Func(x, params + NFuncParams*(NFunc-1)) // use the last parameters
370  } // CompiledGausFitCacheBaseStruct::FuncSum<NFunc, Func>::eval()
371 
372 
373  // partial specialization: 0 of any function
374  template <
375  Double_t Func(Double_t const*, Double_t const*),
376  unsigned int NFuncParams
377  >
379  (Double_t const*, Double_t const*)
380  { return 0.; }
381 
382 
383 
384  // --- CompiledGausFitCacheBaseStruct --------------------------------------
385 
386  template <unsigned int NGaus>
387  void CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector() {
388  if (NGaus > 0) InitializeCompiledGausFitVector<NGaus-1>();
389  AppendFunction<NGaus>();
390  } // CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector()
391 
392 
393  template <>
394  inline void
395  CompiledGausFitCacheBaseStruct::InitializeCompiledGausFitVector<0>()
396  { AppendFunction<0>(); }
397 
398 
399  template <unsigned int NGaus>
400  void CompiledGausFitCacheBaseStruct::AppendFunction() {
401  // create a function in the ficticious range [ 0, 1 ]:
402  funcs.push_back
403  (new TF1(FunctionName(NGaus).c_str(), &ngaus<NGaus>, 0., 1., 3*NGaus));
404  } // CompiledGausFitCacheBaseStruct::AppendFunction()
405 
406 
407  template <unsigned int CutOff>
408  Double_t CompiledGausFitCacheBaseStruct::gaus_trunc
409  (Double_t const* x, Double_t const* params)
410  {
411  const Double_t z = (x[0] - params[1])/params[2];
412  return ((z > -((Double_t) CutOff)) && (z < (Double_t) CutOff))?
413  params[0] * std::exp(-0.5*sqr(z)): 0.;
414  } // CompiledGausFitCacheBaseStruct::gaus_trunc()
415 
416 
417  template <>
418  inline Double_t CompiledGausFitCacheBaseStruct::ngaus<0>
419  (Double_t const* x, Double_t const* params)
420  { return 0.; }
421 
422 
423 
424  // --- CompiledGausFitCacheBaseStruct::InitializeFuncSumVector -------------
425 
426  template <unsigned int NFunc, template <unsigned int> class Func>
427  void
430  {
431  // first fill the lower functions
433  // then add one
434  cache.funcs.push_back(new TF1(
435  cache.FunctionName(NFunc).c_str(), Func<NFunc>::eval,
436  0., 1., Func<NFunc>::NParams
437  ));
438  } // InitializeFuncSumVector<NFunc, Func>::fill()
439 
440 
441  template <template <unsigned int> class Func>
442  void
445  {
446  cache.funcs.push_back
447  (new TF1(cache.FunctionName(0).c_str(), Func<0U>::eval, 0., 1., 0));
448  } // InitializeFuncSumVector<0, Func>::fill()
449 
450  // -------------------------------------------------------------------------
451 
452  } // namespace details
453 
454 
455  // ---------------------------------------------------------------------------
456 
457 } // namespace hit
458 
459 
460 #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:290
constexpr unsigned int StoredMaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:334
std::vector< TF1 * > funcs
Definition: GausFitCache.h:86
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:216
Double_t z
Definition: plot.C:279
CompiledGausFitCache(std::string new_name="CompiledGausFitCache")
Constructor: initializes all the functions.
Definition: GausFitCache.h:286
A sum of NFunc base functions Func.
Definition: GausFitCache.h:135
A set of TF1 linear sum of base functions (Gaussians)
Definition: GausFitCache.h:50
virtual ~GausFitCache()
Destructor.
A set of TF1 linear sum of Gaussians.
Definition: GausFitCache.h:281
A set of TF1 linear sum of truncated Gaussians.
Definition: GausFitCache.h:314
A helper class initializing the function vector.
Definition: GausFitCache.h:245
virtual unsigned int MaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:192
Struct with member type corresponding to the NArg-th type from Args.
Definition: GausFitCache.h:103
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:53
Detector simulation of raw signals on wires.
static Double_t ngaus(Double_t const *x, Double_t const *params)
Definition: GausFitCache.h:210
typename TemplateArgumentHelper< NArg-1, Args... >::type type
Definition: GausFitCache.h:104
constexpr unsigned int StoredMaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:293
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:111
virtual unsigned int MaxGaussians() const
Returns the maximum number of Gaussians in a function that we support.
Definition: GausFitCache.h:331
std::string GetName() const
Return the name of this cache.
Definition: GausFitCache.h:59
Struct with member type corresponding to the NArg-th type from Args.
Definition: GausFitCache.h:110
std::string name
name of the cache
Definition: GausFitCache.h:83
virtual TF1 * GetClone(size_t nGaus)