Cluster.h
Go to the documentation of this file.
1 /** ****************************************************************************
2  * @file Cluster.h
3  * @brief Declaration of cluster object.
4  * @author mitchell.soderberg@yale.edu
5  * @see Cluster.cxx
6  *
7  * Changes:
8  * 20141212 Gianluca Petrillo (petrillo@fnal.gov)
9  * data architecture revision changes (v14)
10  * 20150211 Gianluca Petrillo (petrillo@fnal.gov)
11  * moved from MultipleHitWires() to MultipleHitDensity() (v15)
12  *
13  * ****************************************************************************/
14 
15 #ifndef CLUSTER_H
16 #define CLUSTER_H
17 
18 // C/C++ standard library
19 # include <iosfwd> // std::ostream
20 
21 // LArSoft libraries
22 #include "larcoreobj/SimpleTypesAndConstants/geo_types.h" // geo::PlaneID, geo::View_t
23 
24 
25 namespace recob {
26 
27 
28  /**
29  * @brief Set of hits with a 2D structure
30  *
31  * A cluster is a set of reconstructed hits supposed to originate from the
32  * same physical entity.
33  * A cluster lies in a single plane (of a single TPC).
34  *
35  * Clusters provide the base of reconstructed 3D objects: tracks and showers.
36  * The cluster class contains information that helps characterizing the
37  * originating particle and discriminating its signature as track-like
38  * or shower-like.
39  *
40  * A cluster is supposed to describe the reconstruction of a transiting
41  * particle, and can therefore be thought as having a start, the location
42  * where it is first seen in time, and an end, the location where it is seen
43  * last. In practice, it is often hard to determine by the shape which
44  * tip is which, and in case of showers the end might be hard to determine.
45  * As a consequence, although the two tips are called "start" and "end", their
46  * order is not unerringly; the tip labelled "start" is still deemed to be
47  * more likely the beginning of the cluster rather than the end.
48  * In the extreme case the "end" should be considered just as an alternative
49  * cluster start.
50  *
51  * @note A cluster lives in a plane of inhomogeneous coordinates: wire number
52  * and tick number. Different ways to make them homogeneous are available.
53  * For example, knowing the drift velocity (assuming it constant) and the wire
54  * pitch, it is possible to convert both coordinates in a measure of distance.
55  * Where the wire and time coordinates need to be compared, they are
56  * converted into physical distances. Wire coordinate includes the wire pitch
57  * information and it can be defined as the distance (in centimetres) from the
58  * wire #0 (and negative if it lies on the opposite side than wire #0 with
59  * respect to wire #0) of the point. The tick coordinate is converted into
60  * a distance from the wire plane (in centimetres) by including the drift
61  * velocity. The absolute time for which this coordinate is 0 is defined to
62  * be as an "absolute trigger time". This is still ambiguous enough, but
63  * matter of fact there should be no need of absolute wire or tick coordinates
64  * but only of their difference; for example, to define angles, dT/dW (or some
65  * similar quantity) is used.
66  * More advanced knowledge of the geometry or status of the detector may lead
67  * to different wire pitch or drift velocity: in that case, these quantities
68  * need to be recomputed, although it is conceivable that the ones with simple
69  * constant pitch and drift are often an approximation close enough.
70  */
71  class Cluster {
72 
73  public:
74  typedef int ID_t; ///< Type of cluster ID
75 
76 
77  typedef enum {
78  clStart, ///< Represents the most likely start of the cluster
79  clEnd, ///< Represents the end, or the alternative start, of the cluster
80  NEnds, ///< End count
81  clFirstEnd = 0 ///< Just an alias for loops
82  } ClusterEnds_t; ///< Used to decide which end to use
83 
84  typedef enum {
85  cmFit, ///< Sums from the fitted hit values
86  cmADC, ///< Sums directly from ADC counts
87  NChargeModes, ///< End count
88  cmFirstMode = 0 ///< Just an alias for loops
89  } ChargeMode_t; ///< Used to decide which style of charge sum to use
90 
91 
92  /// Default constructor: an empty cluster
93  Cluster();
94 
95  private:
96 
97  unsigned int fNHits; ///< Number of hits in the cluster
98 
99  /// @name Data referring to start and end of the cluster
100  /// @{
101  /// Wire coordinate of the start and end of the cluster (may lie between wires);
102  /// index is intended to be of type ClusterEnds_t.
103  float fEndWires[NEnds];
104 
105  /// Uncertainty on wire coordinate of the start and end of the cluster;
106  /// index is intended to be of type ClusterEnds_t.
108 
109  /// Tick coordinate of the start and end of the cluster (may be set between ticks);
110  /// index is intended to be of type ClusterEnds_t.
111  float fEndTicks[NEnds];
112 
113  /// Uncertainty on tick coordinate of the start and end of the cluster;
114  /// index is intended to be of type ClusterEnds_t.
116 
117  /// Charge on the start and end wire of the cluster.
118  /// This value can be result of extrapolation or average from a range of hits.
119  /// index is intended to be of type ClusterEnds_t.
121 
122  /// Angle of the start and end of the cluster, defined in [-pi,pi]
123  /// and so that tan(angle) = dT/dW (or, more precisely, `angle = atan2(dT, dW)`).
124  /// The elements are expressed in physical distances and therefore this
125  /// represents a physical angle on the plane orthogonal to the wires in
126  /// the view and containing the drift direction ("x"); the angle is 0 or
127  /// @f$ \pi @f$ when lying on the wire plane, @f$ \pm\pi/2 @f$ when
128  /// pointing into/from the wire plane.
129  /// Index is intended to be of type ClusterEnds_t.
130  float fAngles[NEnds];
131 
132  /// Opening angle of the cluster shape at the start and end of the cluster.
133  /// The coordinates are expressed in physical distances and therefore this
134  /// represents a physical opening angle on the plane orthogonal to the
135  /// wires in the view and containing the drift direction ("x").
136  /// Index is intended to be of type ClusterEnds_t.
138  /// @}
139 
140 
141  /// @name Data derived from hit charge
142  /// @{
143  /// Sum of the charge of all hits in the cluster.
144  /// Index is intended to be of type ChargeMode_t
146 
147  /// Standard deviation of the charge of hits.
148  /// Index is intended to be of type ChargeMode_t
150 
151  ///< Average of the charge of all hits in the cluster (fChargeSum/NHits()).
152  /// Index is intended to be of type ChargeMode_t
154  /// @}
155 
156  /// Density of wires in the cluster with more than one hit.
158 
159  /// A measure of the cluster width, in homogenized units.
160  float fWidth;
161 
162  /// Identifier of this cluster.
163  /// It should be unique per event and per algorithm.
164  /// An invalid cluster can be defined by having an ID Cluster::InvalidID.
165  ID_t fID;
166 
167 
168  geo::View_t fView; ///< View for this cluster
169 
170  geo::PlaneID fPlaneID; ///< Location of the start of the cluster
171 
172 
173  public:
174 
175  /// Type of sentry argument
176  typedef struct {} SentryArgument_t;
177 
178  /// Value for an invalid cluster ID
179  static constexpr ID_t InvalidID = -1;
180 
181  /// An instance of the sentry object
182  static const SentryArgument_t Sentry;
183 
184 
185  /**
186  * @brief Constructor: assigns all the fields
187  * @param start_wire wire coordinate of the start of the cluster
188  * @param sigma_start_wire uncertainty on start_wire
189  * @param start_tick tick coordinate of the start of the cluster
190  * @param sigma_start_tick uncertainty on start_tick
191  * @param start_charge charge on the start wire
192  * @param start_angle angle of the start of the cluster, in [-pi,pi]
193  * @param start_opening opening angle at the start of the cluster
194  * @param end_wire wire coordinate of the end of the cluster
195  * @param sigma_end_wire uncertainty on end_wire
196  * @param end_tick tick coordinate of the end of the cluster
197  * @param sigma_end_tick uncertainty on end_tick
198  * @param end_charge charge on the end wire
199  * @param end_angle angle of the end of the cluster, in [-pi,pi]
200  * @param end_opening opening angle at the end of the cluster
201  * @param integral total charge from fitted shape of hits
202  * @param integral_stddev standard deviation of hit charge from fitted shape
203  * @param summedADC total charge from signal ADC of hits
204  * @param summedADC_stddev standard deviation of signal ADC of hits
205  * @param n_hits number of hits in the cluster
206  * @param multiple_hit_density density of wires with more than one hit
207  * @param width a measure of the cluster width
208  * @param ID cluster ID
209  * @param view view for this cluster
210  * @param plane location of the start of the cluster
211  * @param sentry a sentry instance
212  *
213  * Coordinates are in homogenized units.
214  *
215  * See the documentation of the relative data members for more details on
216  * the definition and constraints of the various constructor arguments.
217  *
218  * @note The sentry parameter can be optionally specified so that the
219  * compiler will realize if the number of parameters in the constructor
220  * has varied.
221  */
222  Cluster(
223  float start_wire,
224  float sigma_start_wire,
225  float start_tick,
226  float sigma_start_tick,
227  float start_charge,
228  float start_angle,
229  float start_opening,
230  float end_wire,
231  float sigma_end_wire,
232  float end_tick,
233  float sigma_end_tick,
234  float end_charge,
235  float end_angle,
236  float end_opening,
237  float integral,
238  float integral_stddev,
239  float summedADC,
240  float summedADC_stddev,
241  unsigned int n_hits,
242  float multiple_hit_density,
243  float width,
244  ID_t ID,
245  geo::View_t view,
246  geo::PlaneID const& plane,
247  SentryArgument_t sentry = Sentry
248  );
249 
250 
251  /// Copy constructor: automatically generated
252  Cluster(Cluster const&) = default;
253 
254  /// Move constructor: as copy, but source cluster gets an invalid ID
255  Cluster(Cluster&& from): Cluster(from) { from.fID = InvalidID; }
256 
257  /// Copy assignment: automatically generated
258  Cluster& operator= (Cluster const&) = default;
259 
260  /// Move assignment: as copy, but source cluster gets an invalid ID
262  {
263  if (&from != this) { operator=(from); from.fID = InvalidID; }
264  return *this;
265  }
266 
267  /// Destructor: automatically generated
268  ~Cluster() = default;
269 
270 
271  /// @{
272  /// @name Accessors
273 
274  /// Number of hits in the cluster
275  unsigned int NHits() const { return fNHits; }
276 
277  /** **********************************************************************
278  * @brief Returns the wire coordinate of the start of the cluster
279  * @return wire coordinate of the start of the cluster (may lie between wires)
280  * @see EndWire(), WireCoord(), StartTick()
281  *
282  * The wire coordinate is in wire units (the homogenized coordinate),
283  * but can have a fractional part describing the relative distance from
284  * the previous wire.
285  */
286  float StartWire() const { return fEndWires[clStart]; }
287 
288  /**
289  * @brief Returns the tick coordinate of the start of the cluster
290  * @return tick coordinate of the start of the cluster (may br fractional)
291  * @see EndTick(), TickCoord(), StartWire()
292  *
293  * The tick coordinate is in tick units (the homogenized coordinate),
294  * but can have a fractional part describing the relative time from
295  * the previous tick.
296  */
297  float StartTick() const { return fEndTicks[clStart]; }
298 
299  /**
300  * @brief Returns the uncertainty on wire coordinate of the start of the cluster
301  * @return uncertainty on wire coordinate of the start of the cluster
302  * @see StartWire()
303  *
304  * The wire uncertainty is in wire units (as for StartWire()).
305  */
306  float SigmaStartWire() const { return fSigmaEndWires[clStart]; }
307 
308  /**
309  * @brief Returns the uncertainty on tick coordinate of the start of the cluster
310  * @return uncertainty on tick coordinate of the start of the cluster
311  * @see StartTick()
312  *
313  * The tick uncertainty is in tick units (as for StartTick()).
314  */
315  float SigmaStartTick() const { return fSigmaEndTicks[clStart]; }
316 
317 
318  /** **********************************************************************
319  * @brief Returns the wire coordinate of the end of the cluster
320  * @return wire coordinate of the end of the cluster (may lie between wires)
321  * @see StartWire(), WireCoord(), EndTick()
322  *
323  * The "end" of the cluster is, in the more ambiguous cluster shapes,
324  * defined as an alternative cluster start.
325  * The wire coordinate is in wire units (the homogenized coordinate),
326  * but can have a fractional part describing the relative distance from
327  * the previous wire.
328  */
329  float EndWire() const { return fEndWires[clEnd]; }
330 
331  /**
332  * @brief Returns the tick coordinate of the end of the cluster
333  * @return tick coordinate of the end of the cluster (may be fractional)
334  * @see StartTick(), TickCoord(), EndWire()
335  *
336  * The "end" of the cluster is, in the more ambiguous cluster shapes,
337  * defined as an alternative cluster start.
338  * The tick coordinate is in tick units (the homogenized coordinate),
339  * but can have a fractional part describing the relative time from
340  * the previous tick.
341  */
342  float EndTick() const { return fEndTicks[clEnd]; }
343 
344  /**
345  * @brief Returns the uncertainty on wire coordinate of the end of the cluster
346  * @return uncertainty on wire coordinate of the end of the cluster
347  * @see EndWire()
348  *
349  * The wire uncertainty is in wire units (as for EndWire()).
350  */
351  float SigmaEndWire() const { return fSigmaEndWires[clEnd]; }
352 
353  /**
354  * @brief Returns the uncertainty on tick coordinate of the end of the cluster
355  * @return uncertainty on tick coordinate of the end of the cluster
356  * @see EndTick()
357  *
358  * The tick uncertainty is in tick units (as for EndTick()).
359  */
360  float SigmaEndTick() const { return fSigmaEndTicks[clEnd]; }
361 
362 
363  //@{
364  /** **********************************************************************
365  * @brief Returns the wire coordinate of one of the end sides of the cluster
366  * @param side clStart for start, clEnd for end of the cluster
367  * @return wire coordinate of the requested end of the cluster (may lie between wires)
368  * @see StartWire(), EndWire(), TickCoord()
369  *
370  * The wire coordinate is in wire units (the homogenized coordinate),
371  * but can have a fractional part describing the relative distance from
372  * the previous wire.
373  *
374  * For algorithms not distinguishing start and end, all the ends can be
375  * tested by the loop:
376  *
377  * for (unsigned int side = recob::Cluster::clFirstEnd;
378  * side < recob::Cluster::NEnds; ++side)
379  * {
380  * float wire = cluster.WireCoord(side);
381  * float tick = cluster.TickCoord(side);
382  * // ...
383  * } // for
384  *
385  */
386  float WireCoord(ClusterEnds_t side) const { return fEndWires[side]; }
387  float WireCoord(unsigned int side) const { return fEndWires[side]; }
388  //@}
389 
390  //@{
391  /**
392  * @brief Returns the tick coordinate of one of the end sides of the cluster
393  * @param side clStart for start, clEnd for end of the cluster
394  * @return tick coordinate of the requested end of the cluster (may be fractional)
395  * @see StartTick(), EndTick(), WireCoord()
396  *
397  * The tick coordinate is in tick units (the homogenized coordinate),
398  * but can have a fractional part describing the relative time from
399  * the previous tick.
400  *
401  * For algorithms not distinguishing start and end, all the ends can be
402  * tested by the loop:
403  *
404  * for (unsigned int side = recob::Cluster::clFirstEnd;
405  * side < recob::Cluster::NEnds; ++side)
406  * {
407  * float wire = cluster.WireCoord(side);
408  * float tick = cluster.TickCoord(side);
409  * // ...
410  * } // for
411  *
412  */
413  float TickCoord(ClusterEnds_t side) const { return fEndTicks[side]; }
414  float TickCoord(unsigned int side) const { return fEndTicks[side]; }
415  //@}
416 
417 
418  //@{
419  /**
420  * @brief Returns the uncertainty on wire coordinate of one of the end sides of the cluster
421  * @param side clStart for start, clEnd for end of the cluster
422  * @return uncertainty on wire coordinate of the requested end of the cluster
423  * @see SigmaStartWire(), SigmaEndWire(), SigmaTickCoord(), TimeCoord()
424  *
425  * Usage of this method is similar to WireCoord().
426  */
427  float SigmaWireCoord(ClusterEnds_t side) const { return fSigmaEndWires[side]; }
428  float SigmaWireCoord(unsigned int side) const { return fSigmaEndWires[side]; }
429  //@}
430 
431  //@{
432  /**
433  * @brief Returns the uncertainty on tick coordinate of one of the end sides of the cluster
434  * @param side clStart for start, clEnd for end of the cluster
435  * @return uncertainty on tick coordinate of the requested end of the cluster
436  * @see SigmaStartTick(), SigmaEndTick(), SigmaWireCoord(), TimeCoord()
437  *
438  * Usage of this method is similar to TimeCoord().
439  */
440  float SigmaTickCoord(ClusterEnds_t side) const { return fSigmaEndTicks[side]; }
441  float SigmaTickCoord(unsigned int side) const { return fSigmaEndTicks[side]; }
442  //@}
443 
444 
445  /** **********************************************************************
446  * @brief Returns the charge on the first wire of the cluster
447  * @return charge on the first wire in ADC counts, negative if not available
448  * @see EndCharge(), EdgeCharge()
449  *
450  * The returned value is in unit of ADC count, although it may be
451  * fractional.
452  * This value can be result of extrapolation or average from a range of hits.
453  */
454  float StartCharge() const { return fEndCharges[clStart]; }
455 
456  /**
457  * @brief Returns the starting angle of the cluster
458  * @return angle in radians
459  * @see EndAngle(), Angle()
460  *
461  * The angle of the group of hits at the start position of the cluster is
462  * returned, defined @f$ \alpha \in [ -\pi, \pi ]@f$ and so that
463  * @f$ \tan(\alpha) = dT/dW @f$ (or, more precisely,
464  * `angle = atan2(dT, dW)`).
465  * The elements are expressed in physical distances and therefore this
466  * represents a physical angle on the plane orthogonal to the wires in
467  * the view and containing the drift direction ("x"); the angle is 0 or
468  * @f$ \pi @f$ when lying on the wire plane, @f$ \pm\pi/2 @f$ when
469  * pointing into/from the wire plane.
470  * The angle is pointing toward the inside of the cluster (that is,
471  * @f$ dW @f$ is positive going from the first wire on).
472  * This value can be result of extrapolation or average from a range of
473  * hits.
474  */
475  float StartAngle() const { return fAngles[clStart]; }
476 
477  /**
478  * @brief Returns the opening angle at the start of the cluster
479  * @return opening angle in radians
480  * @see EndOpeningAngle(), OpeningAngle()
481  *
482  * The returned value is from physical coordinates and in the range
483  * @f$[ 0, \pi ]@f$.
484  */
485  float StartOpeningAngle() const { return fOpeningAngles[clStart]; }
486 
487 
488  /**
489  * @brief Returns the charge on the last wire of the cluster
490  * @return charge on the last wire in ADC counts, negative if not available
491  * @see StartCharge(), EdgeCharge()
492  *
493  * The returned value is in unit of ADC count, although it may be
494  * fractional.
495  * This value can be result of extrapolation or average from a range of
496  * hits.
497  */
498  float EndCharge() const { return fEndCharges[clEnd]; }
499 
500  /**
501  * @brief Returns the ending angle of the cluster
502  * @return angle in radians
503  * @see StartAngle(), Angle()
504  *
505  * The angle of the group of hits at the end position of the cluster is
506  * returned, defined @f$ \alpha \in [ -\pi, \pi ]@f$ and so that
507  * @f$ \tan(\alpha) = dT/dW @f$ (or, more precisely,
508  * `angle = atan2(dT, dW)`).
509  * The elements are expressed in physical distances and therefore this
510  * represents a physical angle on the plane orthogonal to the wires in
511  * the view and containing the drift direction ("x"); the angle is 0 or
512  * @f$ \pi @f$ when lying on the wire plane, @f$ \pm\pi/2 @f$ when
513  * pointing into/from the wire plane.
514  * The angle is pointing toward the outside of the cluster (that is,
515  * @f$ dW @f$ is positive going toward the last wire).
516  * This value can be result of extrapolation or average from a range of
517  * hits.
518  */
519  float EndAngle() const { return fAngles[clEnd]; }
520 
521  /**
522  * @brief Returns the opening angle at the end of the cluster
523  * @return opening angle in radians
524  * @see StartOpeningAngle(), OpeningAngle()
525  *
526  * The returned value is from homogenized coordinates and in the range
527  * @f$[ 0, \pi ]@f$.
528  */
529  float EndOpeningAngle() const { return fOpeningAngles[clEnd]; }
530 
531 
532  //@{
533  /**
534  * @brief Returns the charge on the first or last wire of the cluster
535  * @param side clStart for start, clEnd for end of the cluster
536  * @return charge on the requested wire in ADC counts, negative if not available
537  * @see StartCharge(), EndCharge()
538  *
539  * The returned value is in unit of ADC count, although it may be
540  * fractional.
541  * This value can be result of extrapolation or average from a range of
542  * hits.
543  */
544  float EdgeCharge(ClusterEnds_t side) const { return fEndCharges[side]; }
545  float EdgeCharge(unsigned int side) const { return fEndCharges[side]; }
546  //@}
547 
548  //@{
549  /**
550  * @brief Returns the angle at either end of the cluster
551  * @param side clStart for start, clEnd for end of the cluster
552  * @return angle in radians
553  * @see StartAngle(), EndAngle()
554  *
555  * The angle of the group of hits at the specified position of the cluster
556  * is returned, defined @f$ \alpha \in [ -\pi, \pi ]@f$ and so that
557  * @f$ \tan(\alpha) = dT/dW @f$ (or, more precisely,
558  * `angle = atan2(dT, dW)`).
559  * The elements are expressed in physical distances and therefore this
560  * represents a physical angle on the plane orthogonal to the wires in
561  * the view and containing the drift direction ("x"); the angle is 0 or
562  * @f$ \pi @f$ when lying on the wire plane, @f$ \pm\pi/2 @f$ when
563  * pointing into/from the wire plane.
564  * The angle is pointing so that increasing wire number yields positive
565  * @f$ dW @f$.
566  * This value can be result of extrapolation or average from a range of
567  * hits.
568  */
569  float Angle(ClusterEnds_t side) const { return fAngles[side]; }
570  float Angle(unsigned int side) const { return fAngles[side]; }
571  //@}
572 
573  //@{
574  /**
575  * @brief Returns the opening angle at either end of the cluster
576  * @return opening angle in radians
577  * @see StartOpeningAngle(), EndOpeningAngle()
578  *
579  * The returned value is from homogenized coordinates and in the range
580  * @f$[ 0, \pi ]@f$.
581  * This value can be result of extrapolation or average from a range of
582  * hits.
583  */
584  float OpeningAngle(ClusterEnds_t side) const
585  { return fOpeningAngles[side]; }
586  float OpeningAngle(unsigned int side) const
587  { return fOpeningAngles[side]; }
588  //@}
589 
590 
591  /** **********************************************************************
592  * @brief Returns the total charge of the cluster from hit shape
593  * @return total charge of the cluster from hit shape, in ADC counts
594  * @see IntegralStdDev(), IntegralAverage(), SummedADC(), Charge()
595  *
596  * The total charge is computed as the sum of the charge of all the hits.
597  * The charge of a single hit includes the hit shape (fit) and is obtained
598  * by recob::Hit::Integral().
599  */
600  float Integral() const { return fChargeSum[cmFit]; }
601 
602  /**
603  * @brief Returns the standard deviation of the charge of the cluster hits
604  * @return standard deviation of the charge of the cluster hits, in ADC counts
605  * @see Integral(), IntegralAverage(), SummedADCstdDev(), ChargeStdDev()
606  *
607  * The charge of a single hit includes the hit shape (fit) and is obtained
608  * by recob::Hit::Integral().
609  * It should return 0 if less than two hits are available.
610  */
611  float IntegralStdDev() const { return fChargeStdDev[cmFit]; }
612 
613  /**
614  * @brief Returns the average charge of the cluster hits
615  * @return average of the charge of the cluster hits, in ADC counts
616  * @see Integral(), IntegralStdDev(), SummedADCaverage(), ChargeAverage()
617  *
618  * The charge of a single hit includes the hit shape (fit) and is obtained
619  * by recob::Hit::Integral().
620  * It should return 0 if no hit is available.
621  */
622  float IntegralAverage() const { return fChargeAverage[cmFit]; }
623 
624 
625  /** **********************************************************************
626  * @brief Returns the total charge of the cluster from signal ADC counts
627  * @return total charge of the cluster from signal ADC, in ADC counts
628  * @see SummedADCstdDev(), SummedADCaverage(), Integral(), Charge()
629  *
630  * The total charge is computed as the sum of the charge of all the hits.
631  * The charge of a single hit includes the signal ADC counts and is
632  * obtained by recob::Hit::SummedADC().
633  */
634  float SummedADC() const { return fChargeSum[cmADC]; }
635 
636  /**
637  * @brief Returns the standard deviation of the signal ADC counts of the cluster hits
638  * @return standard deviation of the signal of the cluster hits, in ADC counts
639  * @see SummedADC(), SummedADCaverage(), IntegralStdDev(), ChargeStdDev()
640  *
641  * The charge of a single hit includes the signal ADC counts and is
642  * obtained by recob::Hit::SummedADC().
643  * It should return 0 if less than two hits are available.
644  */
645  float SummedADCstdDev() const { return fChargeStdDev[cmADC]; }
646 
647  /**
648  * @brief Returns the average signal ADC counts of the cluster hits
649  * @return average of the signal of the cluster hits, in ADC counts
650  * @see SummedADC(), SummedADCstdDev(), IntegralAverage(), ChargeAverage()
651  *
652  * The charge of a single hit includes the signal ADC counts and is
653  * obtained by recob::Hit::SummedADC().
654  * It should return 0 if no hit is available.
655  */
656  float SummedADCaverage() const { return fChargeAverage[cmADC]; }
657 
658 
659  //@{
660  /** **********************************************************************
661  * @brief Returns the total charge of the cluster
662  * @param mode cmFit to use fitted hit shape, cmADC for signal ADCs
663  * @return total charge of the cluster, in ADC counts
664  * @see ChargeStdDev(), ChargeAverage(), SummedADC(), Integral()
665  *
666  * The total charge is computed as the sum of the charge of all the hits.
667  * The charge of a single hit comes from the fitted hit shape
668  * (recob::Hit::Integral()) for cmFit, and signal ADC counts
669  * (recob::Hit::SummedADC()) for cmADC.
670  *
671  * @note Cluster class older than version 14 had a Charge() method too;
672  * the new one is not strictly equivalent, although in practice replacing
673  * the old `Charge()` with `Charge(cmFit)` should do the trick.
674  * The recommended update is to use `Integral()` instead.
675  */
676  float Charge(ChargeMode_t mode) const { return fChargeSum[mode]; }
677  float Charge(unsigned int mode) const { return fChargeSum[mode]; }
678  //@}
679 
680  //@{
681  /**
682  * @brief Returns the standard deviation of charge of the cluster hits
683  * @return standard deviation of charge of the cluster hits, in ADC counts
684  * @see Charge(), ChargeAverage(), SummedADCstdDev(), IntegralStdDev()
685  *
686  * The charge of a single hit comes from the fitted hit shape
687  * (recob::Hit::Integral()) for cmFit, and signal ADC counts
688  * (recob::Hit::SummedADC()) for cmADC.
689  * It should return 0 if less than two hits are available.
690  */
691  float ChargeStdDev(ChargeMode_t mode) const
692  { return fChargeStdDev[mode]; }
693  float ChargeStdDev(unsigned int mode) const
694  { return fChargeStdDev[mode]; }
695  //@}
696 
697  //@{
698  /**
699  * @brief Returns the average charge of the cluster hits
700  * @return average of the charge of the cluster hits, in ADC counts
701  * @see Charge(), ChargeStdDev(), SummedADCaverage(), IntegralAverage()
702  *
703  * The charge of a single hit comes from the fitted hit shape
704  * (recob::Hit::Integral()) for cmFit, and signal ADC counts
705  * (recob::Hit::SummedADC()) for cmADC.
706  * It should return 0 if no hit is available.
707  */
708  float ChargeAverage(ChargeMode_t mode) const
709  { return fChargeAverage[mode]; }
710  float ChargeAverage(unsigned int mode) const
711  { return fChargeAverage[mode]; }
712  //@}
713 
714  /**
715  * @brief Density of wires in the cluster with more than one hit
716  * @return density of wires in the cluster with more than one hit
717  *
718  * Returns a quantity defined as NMultiHitWires / Length,
719  * where NMultiHitWires is the number of wires which have more than just
720  * one hit amd Length is an estimation of the length of the cluster, in
721  * centimetres.
722  */
723  float MultipleHitDensity() const { return fMultipleHitDensity; }
724 
725 
726  /// A measure of the cluster width, in homogenized units.
727  float Width() const { return fWidth; }
728 
729 
730  /**
731  * @brief Identifier of this cluster
732  * @return the identifier of this cluster
733  * @see isValid()
734  *
735  * The identifier should be unique per event and per algorithm.
736  * An invalid cluster can be defined by having an ID Cluster::InvalidID.
737  */
738  ID_t ID() const { return fID; }
739 
740  /// Returns the view for this cluster
741  geo::View_t View() const { return fView; }
742 
743  /// Returns the plane ID this cluster lies on
744  geo::PlaneID Plane() const { return fPlaneID; }
745 
746  /// @}
747 
748  /// Returns whether geometry plane is valid
749  bool hasPlane() const { return fPlaneID.isValid; }
750 
751 
752  /// Returns if the cluster is valid (that is, if its ID is not invalid)
753  bool isValid() const { return ID() != InvalidID; }
754 
755 
756  friend std::ostream& operator << (std::ostream& o, Cluster const& c);
757  friend bool operator < (Cluster const& a, Cluster const& b);
758 
759 
760  }; // class Cluster
761 
762 } // namespace recob
763 
764 
765 #endif //CLUSTER_H
Sums from the fitted hit values.
Definition: Cluster.h:85
float SigmaEndTick() const
Returns the uncertainty on tick coordinate of the end of the cluster.
Definition: Cluster.h:360
float fWidth
A measure of the cluster width, in homogenized units.
Definition: Cluster.h:160
static constexpr ID_t InvalidID
Value for an invalid cluster ID.
Definition: Cluster.h:179
float ChargeStdDev(unsigned int mode) const
Definition: Cluster.h:693
float fMultipleHitDensity
Density of wires in the cluster with more than one hit.
Definition: Cluster.h:157
Just an alias for loops.
Definition: Cluster.h:88
float SummedADCaverage() const
Returns the average signal ADC counts of the cluster hits.
Definition: Cluster.h:656
float IntegralAverage() const
Returns the average charge of the cluster hits.
Definition: Cluster.h:622
float SigmaWireCoord(ClusterEnds_t side) const
Returns the uncertainty on wire coordinate of one of the end sides of the cluster.
Definition: Cluster.h:427
Reconstruction base classes.
float Angle(ClusterEnds_t side) const
Returns the angle at either end of the cluster.
Definition: Cluster.h:569
float fEndTicks[NEnds]
Definition: Cluster.h:111
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
float TickCoord(ClusterEnds_t side) const
Returns the tick coordinate of one of the end sides of the cluster.
Definition: Cluster.h:413
float fEndCharges[NEnds]
Definition: Cluster.h:120
float fEndWires[NEnds]
Definition: Cluster.h:103
friend std::ostream & operator<<(std::ostream &o, Cluster const &c)
Definition: Cluster.cxx:173
float WireCoord(unsigned int side) const
Definition: Cluster.h:387
float fSigmaEndTicks[NEnds]
Definition: Cluster.h:115
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
float EdgeCharge(ClusterEnds_t side) const
Returns the charge on the first or last wire of the cluster.
Definition: Cluster.h:544
float SigmaTickCoord(ClusterEnds_t side) const
Returns the uncertainty on tick coordinate of one of the end sides of the cluster.
Definition: Cluster.h:440
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Definition: Cluster.h:286
float fSigmaEndWires[NEnds]
Definition: Cluster.h:107
End count.
Definition: Cluster.h:80
Set of hits with a 2D structure.
Definition: Cluster.h:71
float EndTick() const
Returns the tick coordinate of the end of the cluster.
Definition: Cluster.h:342
float SigmaWireCoord(unsigned int side) const
Definition: Cluster.h:428
float MultipleHitDensity() const
Density of wires in the cluster with more than one hit.
Definition: Cluster.h:723
geo::PlaneID Plane() const
Returns the plane ID this cluster lies on.
Definition: Cluster.h:744
geo::PlaneID fPlaneID
Location of the start of the cluster.
Definition: Cluster.h:170
Type of sentry argument.
Definition: Cluster.h:176
bool isValid() const
Returns if the cluster is valid (that is, if its ID is not invalid)
Definition: Cluster.h:753
float StartAngle() const
Returns the starting angle of the cluster.
Definition: Cluster.h:475
Sums directly from ADC counts.
Definition: Cluster.h:86
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
~Cluster()=default
Destructor: automatically generated.
float SummedADCstdDev() const
Returns the standard deviation of the signal ADC counts of the cluster hits.
Definition: Cluster.h:645
float fChargeSum[NChargeModes]
Definition: Cluster.h:145
float fChargeAverage[NChargeModes]
Definition: Cluster.h:153
float EndCharge() const
Returns the charge on the last wire of the cluster.
Definition: Cluster.h:498
float SummedADC() const
Returns the total charge of the cluster from signal ADC counts.
Definition: Cluster.h:634
Cluster & operator=(Cluster const &)=default
Copy assignment: automatically generated.
float ChargeStdDev(ChargeMode_t mode) const
Returns the standard deviation of charge of the cluster hits.
Definition: Cluster.h:691
float StartOpeningAngle() const
Returns the opening angle at the start of the cluster.
Definition: Cluster.h:485
Represents the most likely start of the cluster.
Definition: Cluster.h:78
Cluster(Cluster &&from)
Move constructor: as copy, but source cluster gets an invalid ID.
Definition: Cluster.h:255
const double a
float Width() const
A measure of the cluster width, in homogenized units.
Definition: Cluster.h:727
float SigmaEndWire() const
Returns the uncertainty on wire coordinate of the end of the cluster.
Definition: Cluster.h:351
float Charge(unsigned int mode) const
Definition: Cluster.h:677
float IntegralStdDev() const
Returns the standard deviation of the charge of the cluster hits.
Definition: Cluster.h:611
float SigmaStartWire() const
Returns the uncertainty on wire coordinate of the start of the cluster.
Definition: Cluster.h:306
float ChargeAverage(unsigned int mode) const
Definition: Cluster.h:710
float WireCoord(ClusterEnds_t side) const
Returns the wire coordinate of one of the end sides of the cluster.
Definition: Cluster.h:386
float fAngles[NEnds]
Definition: Cluster.h:130
Definition of data types for geometry description.
friend bool operator<(Cluster const &a, Cluster const &b)
Definition: Cluster.cxx:196
float EndOpeningAngle() const
Returns the opening angle at the end of the cluster.
Definition: Cluster.h:529
float ChargeAverage(ChargeMode_t mode) const
Returns the average charge of the cluster hits.
Definition: Cluster.h:708
geo::View_t View() const
Returns the view for this cluster.
Definition: Cluster.h:741
float TickCoord(unsigned int side) const
Definition: Cluster.h:414
float StartCharge() const
Returns the charge on the first wire of the cluster.
Definition: Cluster.h:454
ID_t ID() const
Identifier of this cluster.
Definition: Cluster.h:738
unsigned int fNHits
Number of hits in the cluster.
Definition: Cluster.h:97
float EdgeCharge(unsigned int side) const
Definition: Cluster.h:545
float fOpeningAngles[NEnds]
Definition: Cluster.h:137
float SigmaStartTick() const
Returns the uncertainty on tick coordinate of the start of the cluster.
Definition: Cluster.h:315
Just an alias for loops.
Definition: Cluster.h:81
static bool * b
Definition: config.cpp:1043
bool hasPlane() const
Returns whether geometry plane is valid.
Definition: Cluster.h:749
Cluster()
Default constructor: an empty cluster.
Definition: Cluster.cxx:35
float Charge(ChargeMode_t mode) const
Returns the total charge of the cluster.
Definition: Cluster.h:676
unsigned int NHits() const
Number of hits in the cluster.
Definition: Cluster.h:275
float EndAngle() const
Returns the ending angle of the cluster.
Definition: Cluster.h:519
float OpeningAngle(ClusterEnds_t side) const
Returns the opening angle at either end of the cluster.
Definition: Cluster.h:584
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Definition: Cluster.h:297
float Angle(unsigned int side) const
Definition: Cluster.h:570
float OpeningAngle(unsigned int side) const
Definition: Cluster.h:586
float fChargeStdDev[NChargeModes]
Definition: Cluster.h:149
geo::View_t fView
View for this cluster.
Definition: Cluster.h:168
float SigmaTickCoord(unsigned int side) const
Definition: Cluster.h:441
int ID_t
Type of cluster ID.
Definition: Cluster.h:74
Represents the end, or the alternative start, of the cluster.
Definition: Cluster.h:79
float Integral() const
Returns the total charge of the cluster from hit shape.
Definition: Cluster.h:600
float EndWire() const
Returns the wire coordinate of the end of the cluster.
Definition: Cluster.h:329