LineMerger_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // LineMerger class
4 //
5 // maddalena.antonello@lngs.infn.it
6 // ornella.palamara@lngs.infn.it
7 // biagio.rossi@lhep.unibe.ch
8 // msoderbe@syr.edu
9 // joshua.spitz@yale.edu
10 //
11 // This algorithm is designed to merge 2D lines with similar slope and endpoints
12 //
13 ////////////////////////////////////////////////////////////////////////
14 
15 #include <array>
16 #include <cmath> // std::abs(), std::sqrt()
17 #include <iomanip>
18 #include <memory> // std::unique_ptr<>
19 #include <string>
20 #include <utility> // std::move()
21 
22 //Framework includes:
27 #include "canvas/Persistency/Common/FindManyP.h"
29 #include "fhiclcpp/ParameterSet.h"
31 
32 //LArSoft includes:
44 
45 namespace cluster {
46 
47  class LineMerger : public art::EDProducer {
48  public:
49  explicit LineMerger(fhicl::ParameterSet const& pset);
50 
51  private:
52  void produce(art::Event& evt) override;
53 
55  double fSlope; // tolerance for matching angles between two lines (in units of radians)
56  double fEndpointWindow; // tolerance for matching endpoints (in units of time samples)
57 
58  bool SlopeCompatibility(double slope1, double slope2);
59  int EndpointCompatibility(float sclstartwire,
60  float sclstarttime,
61  float sclendwire,
62  float sclendtime,
63  float cl2startwire,
64  float cl2starttime,
65  float cl2endwire,
66  float cl2endtime);
67 
68  }; // class LineMerger
69 
70  /// Class merging clusters: recomputes start and end position and hit list
71  class ClusterMerger {
72  public:
73  // NOTE if you feel like copying this class, move it into its own header
74  // instead, and if you need it for a different hit or hit pointer, make it
75  // a template instead
76  using HitPtr_t = art::Ptr<recob::Hit>; ///< type of pointer to hits
77  using HitVector_t = std::vector<HitPtr_t>; ///< vector of pointers to hits
78 
79  using ID_t = recob::Cluster::ID_t; ///< Type of cluster ID
81 
82  /*
83  typedef enum {
84  clStart, ///< Represents the most likely start of the cluster
85  clEnd, ///< Represents the end, or the alternative start, of the cluster
86  NEnds, ///< End count
87  clFirstEnd = 0 ///< Just an alias for loops
88  } ClusterEnds_t; ///< Used to decide which end to use
89  */
90 
91  ClusterMerger() = default;
92 
93  ClusterMerger(recob::Cluster const& cluster) : ClusterMerger() { Add(cluster); }
94 
95  /**
96  * @brief Merges a single cluster into this object
97  * @param cluster the cluster to be merged
98  * @return whether the addition was successful
99  *
100  * The two ends of the cluster are merged into this one, that gets extended.
101  *
102  * The new cluster must have the same view as the prevopus ones and must lay
103  * on the same plane.
104  * If the new cluster has invalid plane, the current one is kept; if the
105  * current plane is invalid, it is overwritten (that means that if both are
106  * invalid, the merged cluster will also have an invalid plane).
107  *
108  * Note that this code is crap unless the cluster is track-like.
109  */
110  bool Add(recob::Cluster const& cluster);
111 
112  /// @{
113  /// @name Accessors
114 
115  /// Returns the wire coordinate of the start of the cluster
116  float
117  StartWire() const
118  {
119  return fEndWires[ClusterEnds_t::clStart];
120  }
121 
122  /// Returns the tick coordinate of the start of the cluster
123  float
124  StartTick() const
125  {
126  return fEndTicks[ClusterEnds_t::clStart];
127  }
128 
129  /// Returns the uncertainty on wire coordinate of the start of the cluster
130  float
132  {
133  return fSigmaEndWires[ClusterEnds_t::clStart];
134  }
135 
136  // Returns the uncertainty on tick coordinate of the start of the cluster
137  float
139  {
140  return fSigmaEndTicks[ClusterEnds_t::clStart];
141  }
142 
143  /// Returns the wire coordinate of the end of the cluster
144  float
145  EndWire() const
146  {
147  return fEndWires[ClusterEnds_t::clEnd];
148  }
149 
150  /// Returns the tick coordinate of the end of the cluster
151  float
152  EndTick() const
153  {
154  return fEndTicks[ClusterEnds_t::clEnd];
155  }
156 
157  /// Returns the uncertainty on wire coordinate of the end of the cluster
158  float
159  SigmaEndWire() const
160  {
161  return fSigmaEndWires[ClusterEnds_t::clEnd];
162  }
163 
164  /// Returns the uncertainty on tick coordinate of the end of the cluster
165  float
166  SigmaEndTick() const
167  {
168  return fSigmaEndTicks[ClusterEnds_t::clEnd];
169  }
170 
171  /// Returns the wire coordinate of one of the end sides of the cluster
172  float
174  {
175  return fEndWires[side];
176  }
177  // float WireCoord(unsigned int side) const { return fEndWires[side]; }
178 
179  /// Returns the tick coordinate of one of the end sides of the cluster
180  float
182  {
183  return fEndTicks[side];
184  }
185  // float TickCoord(unsigned int side) const { return fEndTicks[side]; }
186 
187  /// Returns the uncertainty on wire coordinate of one of the end sides of the cluster
188  float
190  {
191  return fSigmaEndWires[side];
192  }
193  // float SigmaWireCoord(unsigned int side) const { return fSigmaEndWires[side]; }
194 
195  /// Returns the uncertainty on tick coordinate of one of the end sides of the cluster
196  float
198  {
199  return fSigmaEndTicks[side];
200  }
201  // float SigmaTickCoord(unsigned int side) const { return fSigmaEndTicks[side]; }
202 
203  /// Returns the charge on the first wire of the cluster
204  float
205  StartCharge() const
206  {
207  return fEndCharges[ClusterEnds_t::clStart];
208  }
209 
210  /// Returns the starting angle of the cluster
211  float
212  StartAngle() const
213  {
214  return fAngles[ClusterEnds_t::clStart];
215  }
216 
217  /// Returns the opening angle at the start of the cluster
218  float
220  {
221  return fOpeningAngles[ClusterEnds_t::clStart];
222  }
223 
224  /// Returns the charge on the last wire of the cluster
225  float
226  EndCharge() const
227  {
228  return fEndCharges[ClusterEnds_t::clEnd];
229  }
230 
231  /// Returns the ending angle of the cluster
232  float
233  EndAngle() const
234  {
235  return fAngles[ClusterEnds_t::clEnd];
236  }
237 
238  /// Returns the opening angle at the end of the cluster
239  float
241  {
242  return fOpeningAngles[ClusterEnds_t::clEnd];
243  }
244 
245  /// Returns the charge on the first or last wire of the cluster
246  float
248  {
249  return fEndCharges[side];
250  }
251  // float EdgeCharge(unsigned int side) const { return fEndCharges[side]; }
252 
253  /// Returns the angle at either end of the cluster
254  float
255  Angle(ClusterEnds_t side) const
256  {
257  return fAngles[side];
258  }
259  // float Angle(unsigned int side) const { return fAngles[side]; }
260 
261  /// Returns the opening angle at either end of the cluster
262  float
264  {
265  return fOpeningAngles[side];
266  }
267  // float OpeningAngle(unsigned int side) const { return fOpeningAngles[side]; }
268 
269  /// A measure of the cluster width, in homogenized units.
270  float
271  Width() const
272  {
273  return fWidth;
274  }
275 
276  /// Returns the view for this cluster
278  View() const
279  {
280  return fView;
281  }
282 
283  /// Returns the plane ID this cluster lies on
285  Plane() const
286  {
287  return fPlaneID;
288  }
289 
290  /// Returns whether geometry plane is valid
291  bool
292  hasPlane() const
293  {
294  return Plane().isValid;
295  }
296 
297  protected:
298  /// Data referring to start and end of the cluster
299  float fEndWires[ClusterEnds_t::NEnds];
300 
301  /// Uncertainty on wire coordinate of the start and end of the cluster
302  float fSigmaEndWires[ClusterEnds_t::NEnds];
303 
304  /// Tick coordinate of the start and end of the cluster
305  float fEndTicks[ClusterEnds_t::NEnds];
306 
307  /// Uncertainty on tick coordinate of the start and end of the cluster
308  float fSigmaEndTicks[ClusterEnds_t::NEnds];
309 
310  /// Charge on the start and end wire of the cluster.
311  float fEndCharges[ClusterEnds_t::NEnds];
312 
313  /// Angle of the start and end of the cluster, defined in [-pi,pi]
314  float fAngles[ClusterEnds_t::NEnds];
315 
316  /// Opening angle of the cluster shape at the start and end of the cluster.
317  float fOpeningAngles[ClusterEnds_t::NEnds];
318 
319  /// A measure of the cluster width, in homogenized units.
320  float fWidth;
321 
322  geo::View_t fView; ///< View for this cluster
323 
324  geo::PlaneID fPlaneID; ///< Location of the start of the cluster
325 
326  unsigned int n_clusters = 0; ///< number of clusters added so far
327 
328  /// Imports all the member of the corresponding end
329  void AdoptEnd(recob::Cluster const& cluster, ClusterEnds_t iEnd);
330 
331  template <typename T>
332  static void
334  {
335  if (value > var) var = value;
336  }
337  template <typename T>
338  static void
340  {
341  if (value < var) var = value;
342  }
343  }; // class ClusterMerger
344 
345  void
347  {
348  const ClusterEnds_t iDestEnd = iSrcEnd;
349  fEndWires[iDestEnd] = cluster.WireCoord(iSrcEnd);
350  fSigmaEndWires[iDestEnd] = cluster.SigmaWireCoord(iSrcEnd);
351  fEndTicks[iDestEnd] = cluster.TickCoord(iSrcEnd);
352  fSigmaEndTicks[iDestEnd] = cluster.SigmaTickCoord(iSrcEnd);
353  fEndCharges[iDestEnd] = cluster.EdgeCharge(iSrcEnd);
354  fAngles[iDestEnd] = cluster.Angle(iSrcEnd);
355  fOpeningAngles[iDestEnd] = cluster.OpeningAngle(iSrcEnd);
356  } // ClusterMerger::AdoptEnd()
357 
358  bool
360  {
361  if (!cluster.isValid()) return false;
362 
363  if (n_clusters == 0) { // special case: we are still empty
364  AdoptEnd(cluster, ClusterEnds_t::clStart);
365  AdoptEnd(cluster, ClusterEnds_t::clEnd);
366  fWidth = cluster.Width();
367  fView = cluster.View();
368  fPlaneID = cluster.Plane();
369  ++n_clusters;
370  return true;
371  } // if empty
372 
373  if (cluster.View() != View()) return false;
374 
375  if (cluster.hasPlane() && hasPlane() && (cluster.Plane() != Plane())) return false;
376 
377  // this code has been moved here from the old recon::Cluster::operator+
378  // of recob::Cluster v13.
379  if (cluster.StartWire() < StartWire()) { // adopt the new start
380  AdoptEnd(cluster, ClusterEnds_t::clStart);
381  }
382  if (cluster.EndWire() < EndWire()) { // adopt the new end
383  AdoptEnd(cluster, ClusterEnds_t::clEnd);
384  }
385 
386  top(fWidth, cluster.Width()); // extend width
387 
388  if (!hasPlane()) fPlaneID = cluster.Plane();
389 
390  return true;
391  } // ClusterMerger::Add(Cluster)
392 
393  /// Class merging clusters: recomputes start and end position and hit list
395  public:
396  // NOTE if you feel like copying this class, move it into its own header
397  // instead, and if you need it for a different hit or hit pointer, make it
398  // a template instead
399  using HitPtr_t = art::Ptr<recob::Hit>; ///< type of pointer to hits
400  using HitVector_t = std::vector<HitPtr_t>; ///< vector of pointers to hits
401 
402  ClusterAndHitMerger() = default;
403 
405  {
406  Add(cluster, cluster_hits);
407  }
408 
409  /**
410  * @brief Merges a single cluster into this object
411  * @param cluster the cluster to be merged
412  * @param cluster_hits the list of hits in this cluster
413  * @param prepend if true, hits are inserted at the beginning of the list
414  * @return whether the addition was successful
415  * @see ClusterMerger::Add()
416  *
417  * The two ends of the cluster are merged into this one, that gets extended.
418  * Hit lists are merged too: no check on existing hits nor double addition.
419  *
420  * Note that this code is crap unless the cluster is track-like.
421  */
422  bool Add(recob::Cluster const& cluster, HitVector_t const& cluster_hits, bool prepend = false);
423 
424  /// @{
425  /// @name Accessors
426 
427  /// Returns a constant reference to the current list of hits
428  HitVector_t const&
429  Hits() const
430  {
431  return hits;
432  }
433 
434  /// Number of hits in the cluster
435  unsigned int
436  NHits() const
437  {
438  return hits.size();
439  }
440 
441  ///@}
442 
443  protected:
444  HitVector_t hits; ///< hits in the cluster
445 
446  void
447  AddHits(HitVector_t const& cluster_hits, bool prepend)
448  {
449  hits.insert(prepend ? hits.begin() : hits.end(), cluster_hits.begin(), cluster_hits.end());
450  } // AddHits()
451 
452  }; // class ClusterAndHitMerger
453 
454  bool
456  HitVector_t const& cluster_hits,
457  bool prepend /* = false */
458  )
459  {
460  if (!ClusterMerger::Add(cluster)) return false;
461 
462  AddHits(cluster_hits, prepend);
463  return true;
464  } // ClusterAndHitMerger::Add()
465 
466  //-------------------------------------------------
468  : EDProducer{pset}
469  , fClusterModuleLabel(pset.get<std::string>("ClusterModuleLabel"))
470  , fSlope(pset.get<double>("Slope"))
471  , fEndpointWindow(pset.get<double>("EndpointWindow"))
472  {
473  produces<std::vector<recob::Cluster>>();
474  produces<art::Assns<recob::Cluster, recob::Hit>>();
475  }
476 
477  //------------------------------------------------------------------------------------//
478  void
480  {
481  // Get a Handle for the input Cluster object(s).
482  art::Handle<std::vector<recob::Cluster>> clusterVecHandle;
483  evt.getByLabel(fClusterModuleLabel, clusterVecHandle);
484 
485  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
486  auto const detProp =
488  util::GeometryUtilities const gser{*lar::providerFrom<geo::Geometry>(), clockData, detProp};
489 
490  constexpr size_t nViews = 3; // number of views we map
491 
492  //one vector for each view in the geometry (holds the index of the cluster)
493  std::array<std::vector<size_t>, nViews> ClsIndices;
494 
495  //vector with indicators for whether a cluster has been merged already
496  std::array<std::vector<int>, nViews> Cls_matches;
497 
498  // loop over the input Clusters
499  for (size_t i = 0; i < clusterVecHandle->size(); ++i) {
500 
501  //get a art::Ptr to each Cluster
502  art::Ptr<recob::Cluster> cl(clusterVecHandle, i);
503 
504  size_t view = 0;
505  switch (cl->View()) {
506  case geo::kU: view = 0; break;
507  case geo::kV: view = 1; break;
508  case geo::kZ: view = 2; break;
509  default: continue; // ignore this cluster and process the next one
510  } // end switch on view
511 
512  Cls_matches[view].push_back(0);
513  ClsIndices[view].push_back(i);
514  } // end loop over input clusters
515 
516  auto SuperClusters = std::make_unique<std::vector<recob::Cluster>>();
517  auto assn = std::make_unique<art::Assns<recob::Cluster, recob::Hit>>();
518 
519  // prepare the algorithm to compute the cluster characteristics;
520  // we use the "standard" one here; configuration would happen here,
521  // but we are using the default configuration for that algorithm
523 
524  art::FindManyP<recob::Hit> fmh(clusterVecHandle, evt, fClusterModuleLabel);
525 
526  for (size_t i = 0; i < nViews; ++i) {
527 
528  int clustersfound = 0; // how many merged clusters found in each plane
529  int clsnum1 = 0;
530 
531  for (size_t c = 0; c < ClsIndices[i].size(); ++c) {
532  if (Cls_matches[i][clsnum1] == 1) {
533  ++clsnum1;
534  continue;
535  }
536 
537  // make a new cluster to put into the SuperClusters collection
538  // because we want to be able to adjust it later;
539  // use the hits associated with the current cluster
540  recob::Cluster const& StartingCluster = clusterVecHandle->at(ClsIndices[i][c]);
541  ClusterAndHitMerger cl1(StartingCluster, fmh.at(ClsIndices[i][c]));
542  const recob::Cluster::ID_t clusterID = StartingCluster.ID();
543 
544  Cls_matches[i][clsnum1] = 1;
545  ++clustersfound;
546 
547  int clsnum2 = 0;
548  for (size_t c2 = 0; c2 < ClsIndices[i].size(); ++c2) {
549 
550  if (Cls_matches[i][clsnum2] == 1) {
551  ++clsnum2;
552  continue;
553  }
554 
555  const recob::Cluster& cl2(clusterVecHandle->at(ClsIndices[i][c2]));
556 
557  // check that the slopes are the same
558  // added 13.5 ticks/wirelength in ArgoNeuT.
559  // \todo need to make this detector agnostic
560  // would be nice to have a LArProperties function that returns ticks/wire.
561  bool sameSlope = SlopeCompatibility(cl1.StartAngle(), cl2.EndAngle()) ||
562  SlopeCompatibility(cl1.EndAngle(), cl2.StartAngle());
563 
564  // check that the endpoints fall within a circular window of each other
565  // done in place of intercept matching
566  int sameEndpoint = EndpointCompatibility(cl1.StartWire(),
567  cl1.StartTick(),
568  cl1.EndWire(),
569  cl1.EndTick(),
570  cl2.StartWire(),
571  cl2.StartTick(),
572  cl2.EndWire(),
573  cl2.EndTick());
574 
575  // if the slopes and end points are the same, combine the clusters
576  // note that after 1 combination cl1 is no longer what we started
577  // with
578  if (sameSlope && (sameEndpoint != 0)) {
579  // combine the hit collections too
580  // (find the hits associated with this second cluster);
581  // take into account order when merging hits from two clusters: doc-1776
582  // if sameEndpoint is 1, the new hits come first
583  cl1.Add(cl2, fmh.at(ClsIndices[i][c2]), sameEndpoint == 1);
584  Cls_matches[i][clsnum2] = 1;
585  }
586 
587  ++clsnum2;
588  } // end loop over second cluster iterator
589 
590  // now add the final version of cl1 to the collection of SuperClusters
591  // and create the association between the super cluster and the hits
592  ClusterParamAlgo.ImportHits(gser, cl1.Hits());
593 
594  // create the recob::Cluster directly in the vector
595  SuperClusters->emplace_back(cl1.StartWire(), // start_wire
596  cl1.SigmaStartWire(), // sigma_start_wire
597  cl1.StartTick(), // start_tick
598  cl1.SigmaStartTick(), // sigma_start_tick
599  cl1.StartCharge(), // start_charge
600  cl1.StartAngle(), // start_angle
601  cl1.StartOpeningAngle(), // start_opening
602  cl1.EndWire(), // end_wire
603  cl1.SigmaEndWire(), // sigma_end_wire
604  cl1.EndTick(), // end_time
605  cl1.SigmaEndTick(), // sigma_end_tick
606  cl1.EndCharge(), // end_charge
607  cl1.EndAngle(), // end_angle
608  cl1.EndOpeningAngle(), // end_opening
609  ClusterParamAlgo.Integral().value(), // integral
610  ClusterParamAlgo.IntegralStdDev().value(), // integral_stddev
611  ClusterParamAlgo.SummedADC().value(), // summedADC
612  ClusterParamAlgo.SummedADCStdDev().value(), // summedADC_stddev
613  ClusterParamAlgo.NHits(), // n_hits
614  ClusterParamAlgo.MultipleHitDensity(), // multiple_hit_density
615  cl1.Width(), // width
616  clusterID, // ID
617  cl1.View(), // view
618  cl1.Plane(), // planeID
619  recob::Cluster::Sentry // sentry
620  );
621 
622  util::CreateAssn(evt, *SuperClusters, cl1.Hits(), *assn);
623  ++clsnum1;
624 
625  } // end loop over first cluster iterator
626  } // end loop over planes
627 
628  mf::LogVerbatim("Summary") << std::setfill('-') << std::setw(175) << "-" << std::setfill(' ');
629  mf::LogVerbatim("Summary") << "LineMerger Summary:";
630  for (size_t i = 0; i < SuperClusters->size(); ++i)
631  mf::LogVerbatim("Summary") << SuperClusters->at(i);
632 
633  evt.put(std::move(SuperClusters));
634  evt.put(std::move(assn));
635  }
636 
637  //------------------------------------------------------------------------------------//
638  //checks the difference between angles of the two lines
639  bool
640  LineMerger::SlopeCompatibility(double slope1, double slope2)
641  {
642  double sl1 = atan(slope1);
643  double sl2 = atan(slope2);
644 
645  //the units of fSlope are radians
646  return std::abs(sl1 - sl2) < fSlope;
647  }
648  //------------------------------------------------------------------------------------//
649  int
651  float sclstarttime,
652  float sclendwire,
653  float sclendtime,
654  float cl2startwire,
655  float cl2starttime,
656  float cl2endwire,
657  float cl2endtime)
658  {
659 
660  /// \todo 13.5 ticks/wire. need to make this detector agnostic--spitz
661  float distance =
662  std::sqrt((pow(sclendwire - cl2startwire, 2) * 13.5) + pow(sclendtime - cl2starttime, 2));
663 
664  //not sure if this line is necessary--spitz
665  float distance2 =
666  std::sqrt((pow(sclstartwire - cl2endwire, 2) * 13.5) + pow(sclstarttime - cl2endtime, 2));
667 
668  //determine which way the two clusters should be merged. TY
669  int comp = 0;
670  if (distance < fEndpointWindow)
671  comp = 1;
672  else if (distance2 < fEndpointWindow)
673  comp = -1;
674  return comp;
675  }
676 
678 
679 } // end namespace
float EndOpeningAngle() const
Returns the opening angle at the end of the cluster.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
int EndpointCompatibility(float sclstartwire, float sclstarttime, float sclendwire, float sclendtime, float cl2startwire, float cl2starttime, float cl2endwire, float cl2endtime)
float EndWire() const
Returns the wire coordinate of the end of the cluster.
ClusterAndHitMerger(recob::Cluster const &cluster, HitVector_t const &cluster_hits)
float SigmaStartWire() const
Returns the uncertainty on wire coordinate of the start of the cluster.
float StartAngle() const
Returns the starting angle of the cluster.
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
float EdgeCharge(ClusterEnds_t side) const
Returns the charge on the first or last wire of the cluster.
float Angle(ClusterEnds_t side) const
Returns the angle at either end of the cluster.
Definition: Cluster.h:569
ClusterMerger(recob::Cluster const &cluster)
float SigmaTickCoord(ClusterEnds_t side) const
Returns the uncertainty on tick coordinate of one of the end sides of the cluster.
AdcChannelData::View View
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
void AddHits(TCSlice &slc, Trajectory &tj, unsigned short ipt, bool &sigOK)
Definition: StepUtils.cxx:1037
Planes which measure V.
Definition: geo_types.h:130
float TickCoord(ClusterEnds_t side) const
Returns the tick coordinate of one of the end sides of the cluster.
Definition: Cluster.h:413
void produce(art::Event &evt) override
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
constexpr T pow(T x)
Definition: pow.h:72
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
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
Planes which measure Z direction.
Definition: geo_types.h:132
Set of hits with a 2D structure.
Definition: Cluster.h:71
geo::PlaneID Plane() const
Returns the plane ID this cluster lies on.
Definition: Cluster.h:744
Cluster finding and building.
static void bot(T &var, T value)
float fWidth
A measure of the cluster width, in homogenized units.
bool isValid() const
Returns if the cluster is valid (that is, if its ID is not invalid)
Definition: Cluster.h:753
QAsciiDict< Entry > cl
float StartWire() const
Returns the wire coordinate of the start of the cluster.
art framework interface to geometry description
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
float StartOpeningAngle() const
Returns the opening angle at the start of the cluster.
LineMerger(fhicl::ParameterSet const &pset)
bool Add(recob::Cluster const &cluster, HitVector_t const &cluster_hits, bool prepend=false)
Merges a single cluster into this object.
T abs(T value)
Planes which measure U.
Definition: geo_types.h:129
float TickCoord(ClusterEnds_t side) const
Returns the tick coordinate of one of the end sides of the cluster.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
static void top(T &var, T value)
std::string fClusterModuleLabel
def move(depos, offset)
Definition: depos.py:107
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
void AdoptEnd(recob::Cluster const &cluster, ClusterEnds_t iEnd)
Imports all the member of the corresponding end.
float SigmaEndWire() const
Returns the uncertainty on wire coordinate of the end of the cluster.
float Width() const
A measure of the cluster width, in homogenized units.
Definition: Cluster.h:727
float SigmaEndTick() const
Returns the uncertainty on tick coordinate of the end of the cluster.
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
float Angle(ClusterEnds_t side) const
Returns the angle at either end of the cluster.
float WireCoord(ClusterEnds_t side) const
Returns the wire coordinate of one of the end sides of the cluster.
Definition: Cluster.h:386
Definition of data types for geometry description.
bool hasPlane() const
Returns whether geometry plane is valid.
float SigmaWireCoord(ClusterEnds_t side) const
Returns the uncertainty on wire coordinate of one of the end sides of the cluster.
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Class merging clusters: recomputes start and end position and hit list.
float Width() const
A measure of the cluster width, in homogenized units.
HitVector_t hits
hits in the cluster
HitVector_t const & Hits() const
Returns a constant reference to the current list of hits.
geo::View_t View() const
Returns the view for this cluster.
Definition: Cluster.h:741
Declaration of signal hit object.
geo::View_t fView
View for this cluster.
float StartCharge() const
Returns the charge on the first wire of the cluster.
int var
Definition: 018_def.c:9
float OpeningAngle(ClusterEnds_t side) const
Returns the opening angle at either end of the cluster.
ID_t ID() const
Identifier of this cluster.
Definition: Cluster.h:738
bool SlopeCompatibility(double slope1, double slope2)
unsigned int NHits() const
Number of hits in the cluster.
bool hasPlane() const
Returns whether geometry plane is valid.
Definition: Cluster.h:749
double distance2(double x, double y, double z, double *p)
geo::View_t View() const
Returns the view for this cluster.
Interface to class computing cluster parameters.
TCEvent evt
Definition: DataStructs.cxx:7
geo::PlaneID Plane() const
Returns the plane ID this cluster lies on.
std::vector< HitPtr_t > HitVector_t
vector of pointers to hits
recob::tracking::Plane Plane
Definition: TrackState.h:17
Class merging clusters: recomputes start and end position and hit list.
float OpeningAngle(ClusterEnds_t side) const
Returns the opening angle at either end of the cluster.
Definition: Cluster.h:584
Q_EXPORT QTSManip setfill(int f)
Definition: qtextstream.h:337
float EndAngle() const
Returns the ending angle of the cluster.
recob::Cluster::ID_t ID_t
Type of cluster ID.
float WireCoord(ClusterEnds_t side) const
Returns the wire coordinate of one of the end sides of the cluster.
int ID_t
Type of cluster ID.
Definition: Cluster.h:74
void AddHits(HitVector_t const &cluster_hits, bool prepend)
geo::PlaneID fPlaneID
Location of the start of the cluster.
float EndCharge() const
Returns the charge on the last wire of the cluster.
float EndTick() const
Returns the tick coordinate of the end of the cluster.
bool Add(recob::Cluster const &cluster)
Merges a single cluster into this object.
float EndWire() const
Returns the wire coordinate of the end of the cluster.
Definition: Cluster.h:329