All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OverriddenClusterParamsAlg.h
Go to the documentation of this file.
1 /** ****************************************************************************
2  * @file OverriddenClusterParamsAlg.h
3  * @brief Overrides another ClusterParamsAlgBase class with selected constants
4  * @author petrillo@fnal.gov
5  * @date February 3, 2015
6  * @see StandardClusterParamsAlg.cxx
7  *
8  * ****************************************************************************/
9 
10 #ifndef OVERRIDDENCLUSTERPARAMSALG_H
11 #define OVERRIDDENCLUSTERPARAMSALG_H
12 
13 // C/C++ standard library
14 #include <bitset>
15 #include <type_traits> // std::is_base_of<>
16 #include <utility> // std::forward<>
17 #include <vector>
18 
19 // LArSoft libraries
21 
22 namespace cluster {
23  namespace details {
24  /**
25  * @brief Class holding a value of one among some selected types...
26  *
27  * FIXME: If this functionality is necessary, it should be
28  * replaced with std::variant.
29  */
30  class MultiValue {
31  public:
33 
34  union {
36  float float_value;
37  size_t size_t_value;
38  };
39 
40  /// Default constructor; it's here only to allow for vectors to be resized
41  /// and its effect is undefined. This class is not to be considered valid
42  /// until it's assigned a value with the operator= .
44 
45  /// Sets the value from a value of type T; undefined by default
46  template <typename T>
48 
49  /// Converts the value to type T; undefined by default
50  template <typename T>
51  operator T() const;
52 
53  }; // MultiValue
54 
55  } // namespace details
56 
57  /** **************************************************************************
58  * @brief Algorithm collection class computing cluster parameters
59  * @tparam AlgoBase class of algorithms to be overridden
60  * @see ClusterParamsAlg
61  *
62  * This class wraps a ClusterParamsAlgBase class, and overrides selected
63  * methods with constant values.
64  * The same effect can be obtained explicitly creating a new class with
65  * the proper methods overridden. This one is a more convenient way to get
66  * the same result, but it's slower and less flexible.
67  */
68  template <typename AlgoBase>
71  "OverriddenClusterParamsAlg template parameter must derive"
72  " from ClusterParamsAlgBase");
73 
74  public:
75  using Algo_t = AlgoBase;
77  using Measure_t = typename AlgoBase::Measure_t;
78 
80  cpStartAngle, ///< StartAngle()
81  cpEndAngle, ///< EndAngle()
82  cpStartCharge, ///< StartCharge()
83  cpEndCharge, ///< EndCharge()
84  cpStartOpeningAngle, ///< StartOpeningAngle()
85  cpEndOpeningAngle, ///< EndOpeningAngle()
86  cpIntegral, ///< Integral()
87  cpIntegralStdDev, ///< IntegralStdDev()
88  cpSummedADC, ///< SummedADC()
89  cpSummedADCStdDev, ///< SummedADCStdDev()
90  cpNHits, ///< NHits()
91  cpMultipleHitDensity, ///< MultipleHitDensity()
92  cpWidth, ///< Width()
93  NParameters ///< total number of supported parameters
94  }; ///< type of cluster parameters
95 
96  /// Constructor; just forwards the arguments to the base class
97  template <typename... Args>
98  explicit OverriddenClusterParamsAlg(Args&&... args)
99  : algo(std::forward<Args>(args)...), values(NParameters)
100  {}
101 
102  /**
103  * @brief Overrides the specified cluster parameter
104  * @param param which cluster parameter to override
105  * @param value the value of the cluster parameter to be returned
106  * @return this object
107  * @see ReleaseParameter()
108  *
109  * For parameters without uncertainty, the uncertainty will be ignored.
110  */
111  This_t&
113  {
114  overridden_set.set((size_t)param);
115  values[(size_t)param] = value;
116  return *this;
117  } // OverrideParameter()
118 
119  /**
120  * @brief Cancels the override of the specified cluster parameter
121  * @param param which cluster parameter not to override any more
122  * @return this object
123  * @see OverrideParameter()
124  */
125  This_t&
127  {
128  overridden_set.set((size_t)param);
129  return *this;
130  }
131 
132  /// Returns whether the specified parameter is currently overridden
133  bool
135  {
136  return overridden_set.test((size_t)param);
137  }
138 
139  /// @{
140  /// @name Standard ClusterParamsAlgBase interface
141  ///
142  /// The following methods replicate the ones of the templated Algo_t class.
143  /// Except, of course, when they are overridden.
144 
145  /**
146  * @brief Restores the class to post-configuration, pre-initialization state
147  * @see Algo_t::Clear()
148  */
149  void
150  Clear() override
151  {
152  algo.Clear();
153  }
154 
155  /**
156  * @brief Sets the list of input hits
157  * @param hits list of pointers to hits
158  * @throw undefined in case of error, this method can throw (anything)
159  * @see Algo_t::SetHits().
160  */
161  void
163  std::vector<recob::Hit const*> const& hits) override
164  {
165  algo.SetHits(gser, hits);
166  }
167 
168  /**
169  * @brief Sets the list of input hits
170  * @param hits list of hits (hits will not be modified)
171  * @throw undefined in case of error, this method can throw (anything)
172  * @see Algo_t::SetHits().
173  */
174  void
175  SetHits(util::GeometryUtilities const& gser, std::vector<recob::Hit> const& hits) override
176  {
177  algo.SetHits(gser, hits);
178  }
179 
180  /// Set the verbosity level; @see Algo_t::SetVerbose().
181  void
182  SetVerbose(int level = 1) override
183  {
185  algo.SetVerbose(level);
186  }
187 
188  /// @{
189  /// @name Algorithm results
190 
191  //@{
192  /**
193  * @brief Computes the charge on the first and last wire of the track
194  * @return the charge in ADC counts, with uncertainty
195  * @see Algo_t::StartCharge(), Algo_t::EndCharge()
196  */
197  Measure_t
198  StartCharge(util::GeometryUtilities const& gser) override
199  {
200  return ReturnValue(cpStartCharge, &Algo_t::StartCharge, gser);
201  }
202  Measure_t
203  EndCharge(util::GeometryUtilities const& gser) override
204  {
205  return ReturnValue(cpEndCharge, &Algo_t::EndCharge, gser);
206  }
207  //@}
208 
209  //@{
210  /**
211  * @brief Computes the angle of the cluster
212  * @return angle of the cluster in the wire x time space, in radians
213  * @see Algo_t::StartAngle(), Algo_t::EndAngle()
214  *
215  * The angle is in the @f$ [ -\pi, \pi ] @f$ range, with 0 corresponding to
216  * a cluster parallel to the wire plane and @f$ \pi @f$ to a cluster
217  * orthogonal to the wire plane, going farther from it.
218  */
219  Measure_t
220  StartAngle() override
221  {
222  return ReturnValue(cpStartAngle, &Algo_t::StartAngle);
223  }
224 
225  Measure_t
226  EndAngle() override
227  {
228  return ReturnValue(cpEndAngle, &Algo_t::EndAngle);
229  }
230  //@}
231 
232  //@{
233  /**
234  * @brief Computes the opening angle at the start or end of the cluster
235  * @return angle at the start of the cluster, in radians
236  * @see Algo_t::StartOpeningAngle(), Algo_t::EndOpeningAngle()
237  */
238  Measure_t
239  StartOpeningAngle() override
240  {
241  return ReturnValue(cpStartOpeningAngle, &Algo_t::StartOpeningAngle);
242  }
243  Measure_t
244  EndOpeningAngle() override
245  {
246  return ReturnValue(cpEndOpeningAngle, &Algo_t::EndOpeningAngle);
247  }
248  //@}
249 
250  /// @name Cluster charge
251  /// @{
252  /**
253  * @brief Computes the total charge of the cluster from Hit::Integral()
254  * @return total charge of the cluster, in ADC count units
255  * @see IntegralStdDev(), SummedADC()
256  * @see Algo_t::Integral()
257  */
258  Measure_t
259  Integral() override
260  {
261  return ReturnValue(cpIntegral, &Algo_t::Integral);
262  }
263 
264  /**
265  * @brief Computes the standard deviation on the charge of the cluster hits
266  * @return the standard deviation of charge of hits, in ADC count units
267  * @see Integral()
268  * @see Algo_t::IntegralStdDev()
269  */
270  Measure_t
271  IntegralStdDev() override
272  {
273  return ReturnValue(cpIntegralStdDev, &Algo_t::IntegralStdDev);
274  }
275 
276  /**
277  * @brief Computes the total charge of the cluster from Hit::SummedADC()
278  * @return total charge of the cluster, in ADC count units
279  * @see SummedADCStdDev(), Integral()
280  * @see Algo_t::SummedADC()
281  */
282  Measure_t
283  SummedADC() override
284  {
285  return ReturnValue(cpSummedADC, &Algo_t::SummedADC);
286  }
287 
288  /**
289  * @brief Computes the standard deviation on the charge of the cluster hits
290  * @return the standard deviation of charge of hits, in ADC count units
291  * @see SummedADC()
292  * @see Algo_t::SummedADCStdDev()
293  */
294  Measure_t
295  SummedADCStdDev() override
296  {
297  return ReturnValue(cpSummedADCStdDev, &Algo_t::SummedADCStdDev);
298  }
299 
300  /// @}
301 
302  /// Returns the number of hits in the cluster
303  size_t
304  NHits() override
305  {
306  return ReturnValue(cpNHits, &Algo_t::NHits);
307  }
308 
309  /**
310  * @brief Fraction of wires in the cluster with more than one hit
311  * @return fraction of wires with more than one hit, or 0 if no wires
312  * @see Algo_t::MultipleHitDensity()
313  */
314  float
316  {
317  return ReturnValue(cpMultipleHitDensity, &Algo_t::MultipleHitDensity);
318  }
319 
320  /**
321  * @brief Computes the width of the cluster
322  * @return width of the cluster
323  * @see Algo_t::Width()
324  */
325  float
326  Width(util::GeometryUtilities const& gser) override
327  {
328  return ReturnValue(cpWidth, &Algo_t::Width, gser);
329  }
330 
331  /// @}
332 
333  /// @}
334 
335  protected:
336  using ValueFunction_t = float (Algo_t::*)();
338 
339  Algo_t algo; ///< an instance of the wrapped algorithm class
340 
341  std::vector<details::MultiValue> values; ///< the overridden values
342  std::bitset<NParameters> overridden_set; ///< bits for overriding
343 
344  template <typename Func, typename... Args>
345  auto
346  ReturnValue(ParameterType_t param, Func func, Args&&... args) -> decltype((algo.*func)(args...))
347  {
348  if (isOverridden(param)) {
349  // convert here to the return type of the function
350  // (even if we are not using that function, it still defines the type)
351  return values[(size_t)param];
352  }
353  else
354  return (algo.*func)(args...);
355  } // ReturnValue()
356 
357  }; // class OverriddenClusterParamsAlg
358 
359 } // namespace cluster
360 
361 //==============================================================================
362 //=== Template implementation
363 //==============================================================================
364 
365 namespace cluster {
366 
367  namespace details {
368 
369  // specialization: size_t
370  template <>
371  MultiValue&
373  {
375  return *this;
376  }
377 
378  template <>
379  MultiValue::operator size_t() const
380  {
381  return size_t_value;
382  }
383 
384  // specialization: float
385  template <>
386  MultiValue&
388  {
389  float_value = value;
390  return *this;
391  }
392 
393  template <>
394  MultiValue::operator float() const
395  {
396  return float_value;
397  }
398 
399  // specialization: Measure_t
400  template <>
401  MultiValue&
403  {
405  return *this;
406  }
407 
408  template <>
409  MultiValue::operator MultiValue::Measure_t() const
410  {
411  return measure_value;
412  }
413 
414  } // namespace details
415 } // namespace cluster
416 
417 #endif // OVERRIDDENCLUSTERPARAMSALG_H
float Width(util::GeometryUtilities const &gser) override
Computes the width of the cluster.
void SetHits(util::GeometryUtilities const &gser, std::vector< recob::Hit > const &hits) override
Sets the list of input hits.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
Measure_t EndCharge(util::GeometryUtilities const &gser) override
void SetHits(util::GeometryUtilities const &gser, std::vector< recob::Hit const * > const &hits) override
Sets the list of input hits.
std::bitset< NParameters > overridden_set
bits for overriding
bool isOverridden(ParameterType_t param) const
Returns whether the specified parameter is currently overridden.
Measure_t StartCharge(util::GeometryUtilities const &gser) override
Computes the charge on the first and last wire of the track.
process_name cluster
Definition: cheaterreco.fcl:51
std::vector< details::MultiValue > values
the overridden values
Class holding a value of one among some selected types...
Measure_t Integral() override
Computes the total charge of the cluster from Hit::Integral()
virtual void SetVerbose(int level=1)
Set the verbosity level.
Measure_t StartOpeningAngle() override
Computes the opening angle at the start or end of the cluster.
Measure_t StartAngle() override
Computes the angle of the cluster.
OverriddenClusterParamsAlg< AlgoBase > This_t
Algo_t algo
an instance of the wrapped algorithm class
Algorithm collection class computing cluster parameters.
float MultipleHitDensity() override
Fraction of wires in the cluster with more than one hit.
size_t NHits() override
Returns the number of hits in the cluster.
Measure_t IntegralStdDev() override
Computes the standard deviation on the charge of the cluster hits.
This_t & ReleaseParameter(ParameterType_t param)
Cancels the override of the specified cluster parameter.
cluster::details::Measure_t< float > Measure_t
MultiValue & operator=(T)
Sets the value from a value of type T; undefined by default.
OverriddenClusterParamsAlg(Args &&...args)
Constructor; just forwards the arguments to the base class.
Interface for a algorithm class computing cluster parameters.
Measure_t SummedADC() override
Computes the total charge of the cluster from Hit::SummedADC()
temporary value
void SetVerbose(int level=1) override
Set the verbosity level;.
Algorithm collection class computing cluster parameters.
Measure_t SummedADCStdDev() override
Computes the standard deviation on the charge of the cluster hits.
void Clear() override
Restores the class to post-configuration, pre-initialization state.
This_t & OverrideParameter(ParameterType_t param, Measure_t value)
Overrides the specified cluster parameter.
auto ReturnValue(ParameterType_t param, Func func, Args &&...args) -> decltype((algo.*func)(args...))