LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ClusterCrawlerAlg.h
Go to the documentation of this file.
1 // ClusterCrawlerAlg.h
3 //
4 // ClusterCrawlerAlg class
5 //
6 // Bruce Baller
7 //
9 #ifndef CLUSTERCRAWLERALG_H
10 #define CLUSTERCRAWLERALG_H
11 
12 // C/C++ standard libraries
13 #include <array>
14 #include <utility> // std::pair<>
15 #include <vector>
16 
17 // framework libraries
19 namespace geo {
20  class Geometry;
21 }
22 
23 // LArSoft libraries
28 namespace detinfo {
29  class DetectorClocksData;
30  class DetectorPropertiesData;
31 }
32 
33 namespace cluster {
34 
36  public:
37  // some functions to handle the CTP_t type
38  typedef unsigned int CTP_t;
39 
40  static constexpr unsigned int CTPpad = 1000; // alignment for CTP sub-items
41  static CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
42  {
43  return cryo * CTPpad * CTPpad + tpc * CTPpad + plane;
44  }
45  static CTP_t EncodeCTP(const geo::PlaneID& planeID)
46  {
47  return EncodeCTP(planeID.Cryostat, planeID.TPC, planeID.Plane);
48  }
49  static geo::PlaneID DecodeCTP(CTP_t CTP)
50  {
51  return {CTP / (CTPpad * CTPpad), CTP / CTPpad % CTPpad, CTP % CTPpad};
52  }
53 
56 
58  struct ClusterStore {
59  short ID; // Cluster ID. ID < 0 = abandoned cluster
60  short ProcCode; // Processor code for debugging
61  short StopCode; // code for the reason for stopping cluster tracking
62  CTP_t CTP; // Cryostat/TPC/Plane code
63  float BeginSlp; // beginning slope (= DS end = high wire number)
64  float BeginSlpErr; // error
65  float BeginAng;
66  unsigned int BeginWir; // begin wire
67  float BeginTim; // begin time
68  float BeginChg; // beginning average charge
69  float BeginChgNear; // charge near the cluster Begin
70  short BeginVtx; // ID of the Begin vertex
71  float EndSlp; // end slope (= US end = low wire number)
72  float EndAng;
73  float EndSlpErr; // error
74  unsigned int EndWir; // end wire
75  float EndTim; // ending time
76  float EndChg; // ending average charge
77  float EndChgNear; // charge near the cluster End
78  short EndVtx; // ID of the end vertex
79  std::vector<unsigned int> tclhits; // hits on the cluster
80  }; // ClusterStore
81 
83  struct VtxStore {
84  float Wire;
85  float WireErr;
86  float Time;
87  float TimeErr;
88  unsigned short NClusters; // = 0 for abandoned vertices
89  float ChiDOF;
90  short Topo; // 1 = US-US, 2 = US-DS, 3 = DS-US, 4 = DS-DS, 5 = Star,
91  // 6 = hammer, 7 = vtx3clustermatch, 8 = vtx3clustersplit, 9 = FindTrajVertices
92  CTP_t CTP;
93  bool Fixed; // Vertex position fixed (should not be re-fit)
94  };
95 
97  struct Vtx3Store {
98  std::array<short, 3> Ptr2D; // pointers to 2D vertices in each plane
99  float X; // x position
100  float XErr; // x position error
101  float Y; // y position
102  float YErr; // y position error
103  float Z; // z position
104  float ZErr; // z position error
105  short Wire; // wire number for an incomplete 3D vertex
106  unsigned short CStat;
107  unsigned short TPC;
108  unsigned short ProcCode;
109  };
110 
111  explicit ClusterCrawlerAlg(fhicl::ParameterSet const& pset);
112 
113  void RunCrawler(detinfo::DetectorClocksData const& clock_data,
114  detinfo::DetectorPropertiesData const& det_prop,
115  std::vector<recob::Hit> const& srchits);
116 
119 
120  std::vector<short> const& GetinClus() const { return inClus; }
121 
123  std::vector<recob::Hit>&& YieldHits() { return std::move(fHits); }
124 
126  std::vector<recob::Hit> GetHits() { return fHits; }
127 
129  std::vector<ClusterStore> const& GetClusters() const { return tcl; }
130 
132  std::vector<VtxStore> const& GetEndPoints() const { return vtx; }
133 
135  std::vector<Vtx3Store> const& GetVertices() const { return vtx3; }
136 
139  void ClearResults();
140 
142 
144  static bool SortByMultiplet(recob::Hit const& a, recob::Hit const& b);
145 
147 
148  private:
149  unsigned short fNumPass;
150  std::vector<unsigned short> fMaxHitsFit;
151  std::vector<unsigned short> fMinHits;
152  std::vector<unsigned short> fNHitsAve;
153  std::vector<float> fChiCut;
155  std::vector<float> fKinkChiRat;
156  std::vector<float> fKinkAngCut;
158  std::vector<float> fChgCut;
159  std::vector<unsigned short>
161  std::vector<unsigned short> fMinWirAfterSkip;
162  std::vector<bool> fDoMerge;
164  std::vector<float> fTimeDelta;
165  std::vector<float> fMergeChgCut;
166  std::vector<bool> fFindVertices;
167  std::vector<bool> fLACrawl;
169  // bool fFindVLAClusters; ///< look for Very Large Angle clusters
171 
172  std::vector<float> fMinAmp;
173 
178  // bool fFindTrajVertices;
179 
180  // global cuts and parameters
181  float fHitErrFac;
182  float fHitMinAmp;
184  float fMinHitFrac;
186  unsigned short fLAClusMaxHitsFit;
190  float fMergeOverlapAngCut;
192  unsigned short fAllowNoHitWire;
193  float fVertex2DCut;
195  float fVertex3DCut;
196 
199  int fDebugHit;
200 
201  // Wires that have been determined by some filter (e.g. NoiseFilter) to be good
202  std::vector<geo::WireID> fFilteredWires;
203 
204  // these variables define the cluster used during crawling
205  float clpar[3];
206  float clparerr[2];
208  float clChisq;
209  float fAveChg;
210  // float fChgRMS; ///< average charge RMS at leading edge of cluster
211  float fChgSlp;
212  float fAveHitWidth;
213 
214  bool prt;
215  bool vtxprt;
216  unsigned short NClusters;
217 
219 
220  std::vector<recob::Hit> fHits;
221  std::vector<short> inClus;
222  std::vector<bool> mergeAvailable;
223  std::vector<ClusterStore> tcl;
224  std::vector<VtxStore> vtx;
225  std::vector<Vtx3Store> vtx3;
226 
228 
229  float clBeginSlp;
230  float clBeginAng;
232  unsigned int clBeginWir;
233  float clBeginTim;
234  float clBeginChg;
236  float clEndSlp;
237  float clEndAng;
238  float clEndSlpErr;
239  unsigned int clEndWir;
240  float clEndTim;
241  float clEndChg;
242  float clEndChgNear;
243  short clStopCode;
244  short clProcCode;
254  CTP_t clCTP;
266  bool clLA;
267 
268  unsigned int fFirstWire;
269  unsigned int fFirstHit;
270  unsigned int fLastWire;
271  unsigned int cstat; // the current cryostat
272  unsigned int tpc; // the current TPC
273  unsigned int plane; // the current plane
274  unsigned int fNumWires; // number of wires in the current plane
275  unsigned int fMaxTime; // number of time samples in the current plane
276  float fScaleF;
277 
278  unsigned short pass;
279 
280  // vector of pairs of first (.first) and last+1 (.second) hit on each wire
281  // in the range fFirstWire to fLastWire. A value of -2 indicates that there
282  // are no hits on the wire. A value of -1 indicates that the wire is dead
283  std::vector<std::pair<int, int>> WireHitRange;
284 
285  std::vector<unsigned int> fcl2hits;
286  std::vector<float> chifits;
287  std::vector<short> hitNear;
288 
290  std::vector<float> chgNear;
292  float fChgNearCut;
293 
295  std::string fhitsModuleLabel;
296  // ******** crawling routines *****************
297 
298  // Loops over wires looking for seed clusters
299  void ClusterLoop();
300  // Returns true if the hits on a cluster have a consistent width
301  bool ClusterHitsOK(short nHitChk);
302  // Finds a hit on wire kwire, adds it to the cluster and re-fits it
303  void AddHit(unsigned int kwire, bool& HitOK, bool& SigOK);
304  // Finds a hit on wire kwire, adds it to a LargeAngle cluster and re-fits it
305  void AddLAHit(unsigned int kwire, bool& ChkCharge, bool& HitOK, bool& SigOK);
306  // Fits the cluster hits in fcl2hits to a straight line
307  void FitCluster();
308  // Fits the charge of the cluster hits in fcl2hits
309  void FitClusterChg();
310  // Fits the middle of a temporary cluster it1 using hits iht to iht + nhit
311  void FitClusterMid(unsigned short it1, unsigned int iht, short nhit);
312  void FitClusterMid(std::vector<unsigned int>& hitVec, unsigned int iht, short nhit);
313  // Crawls along a trail of hits UpStream
314  void CrawlUS();
315  // Crawls along a trail of hits UpStream - Large Angle version
316  void LACrawlUS();
317 
318  void KillGarbageClusters();
319 
320  // ************** cluster merging routines *******************
321 
322  // Compares two cluster combinations to see if they should be merged
323  void ChkMerge();
324  // Checks merge for cluster cl2 within the bounds of cl1
325  void ChkMerge12(unsigned short it1, unsigned short it2, bool& didit);
326  // Merges clusters cl1 and cl2
327  void DoMerge(unsigned short it1, unsigned short it2, short ProcCode);
328 
329  // ************** hit merging routines *******************
330  // check the number of nearby hits to the ones added to the current cluster.
331  // If there are too many, merge the hits and re-fit
332  void ChkClusterNearbyHits(bool prt);
333  // merge the hits in a multiplet into one hit
334  void MergeHits(const unsigned int theHit, bool& didMerge);
336  void FixMultipletLocalIndices(size_t begin, size_t end, short int multiplicity = -1);
337 
338  // ************** cluster finish routines *******************
339 
340  // Check the fraction of wires with hits
341  void CheckClusterHitFrac(bool prt);
342 
343  // Try to extend clusters downstream
344  void ChkClusterDS();
345 
346  // Try to merge overlapping clusters
347  void MergeOverlap();
348 
350  void MakeClusterObsolete(unsigned short icl);
352  void RestoreObsoleteCluster(unsigned short icl);
353 
355  void RemoveObsoleteHits();
356 
357  // ************** 2D vertex routines *******************
358 
359  // Find 2D vertices
360  void FindVertices();
361  // Find 2D star topology vertices
362  void FindStarVertices();
363  // check a vertex (vw, fvt) made with clusters it1, and it2 against the
364  // vector of existing clusters
365  void ChkVertex(float fvw, float fvt, unsigned short it1, unsigned short it2, short topo);
366  // try to attach a cluster to an existing vertex
367  void ClusterVertex(unsigned short it2);
368  // try to attach a cluster to a specified vertex
369  void VertexCluster(unsigned short ivx);
370  // Refine cluster ends near vertices
371  void RefineVertexClusters(unsigned short ivx);
372  // Split clusters that cross a vertex
373  bool VtxClusterSplit();
374  // returns true if a vertex is encountered while crawling
375  bool CrawlVtxChk(unsigned int kwire);
376  // returns true if this cluster is between a vertex and another
377  // cluster that is associated with the vertex
378  bool CrawlVtxChk2();
379  // use a vertex constraint to start a cluster
380  void VtxConstraint(unsigned int iwire,
381  unsigned int ihit,
382  unsigned int jwire,
383  unsigned int& useHit,
384  bool& doConstrain);
385  // fit the vertex position
386  void FitVtx(unsigned short iv);
387  // weight and fit all vertices
388  void FitAllVtx(CTP_t inCTP);
389 
390  // ************** 3D vertex routines *******************
391 
392  // match vertices between planes
393  void VtxMatch(detinfo::DetectorPropertiesData const& det_prop, geo::TPCID const& tpcid);
394  // Match clusters to endpoints using 3D vertex information
395  void Vtx3ClusterMatch(detinfo::DetectorPropertiesData const& det_prop, geo::TPCID const& tpcid);
396  // split clusters using 3D vertex information
397  void Vtx3ClusterSplit(detinfo::DetectorPropertiesData const& det_prop, geo::TPCID const& tpcid);
398  // look for a long cluster that stops at a short cluster in two views
399  void FindHammerClusters(detinfo::DetectorPropertiesData const& det_prop);
400 
401  // ************** utility routines *******************
402 
403  // inits everything
404  void CrawlInit();
405  // inits the cluster stuff
406  void ClusterInit();
407  // fills the wirehitrange vector for the supplied Cryostat/TPC/Plane code
408  void GetHitRange(CTP_t CTP);
409  // Stores cluster information in a temporary vector
410  bool TmpStore();
411  // Gets a temp cluster and puts it into the working cluster variables
412  void TmpGet(unsigned short it1);
413  // Does just what it says
414  void CalculateAveHitWidth();
415  // Shortens the fcl2hits, chifits, etc vectors by the specified amount
416  void FclTrimUS(unsigned short nTrim);
417  // Splits a cluster into two clusters at position pos. Associates the
418  // new clusters with a vertex
419  bool SplitCluster(unsigned short icl, unsigned short pos, unsigned short ivx);
420  // Counts the number of dead wires in the range spanned by fcl2hits
421  unsigned int DeadWireCount();
422  unsigned int DeadWireCount(unsigned int inWire1, unsigned int inWire2);
423  // return true if the pre-merged it1 and it2 clusters will meet the quality requirement
424  bool ChkMergedClusterHitFrac(unsigned short it1, unsigned short it2);
425  // Prints cluster information to the screen
426  void PrintClusters();
427  void PrintVertices();
428  // check for a signal on all wires between two points
429  bool ChkSignal(unsigned int iht, unsigned int jht);
430  bool ChkSignal(unsigned int wire1, float time1, unsigned int wire2, float time2);
431  // returns an angle-dependent scale factor for weighting fits, etc
432  float AngleFactor(float slope);
433  // calculate the kink angle between hits 0-2 and 3 - 5 on the leading edge of
434  // the cluster under construction
435  float EndKinkAngle();
437  bool CheckHitDuplicates(std::string location, std::string marker = "") const;
438  // Find the distance of closest approach between the end of a cluster and a (wire,tick) position
439  float DoCA(short icl, unsigned short end, float vwire, float vtick);
440  // Find the Chisq/DOF between the end of a cluster and a (wire,tick) position
441  float ClusterVertexChi(short icl, unsigned short end, unsigned short ivx);
442  // Find the Chisq/DOF between a point and a vertex
443  float PointVertexChi(float wire, float tick, unsigned short ivx);
444  std::string PrintHit(unsigned int iht);
445 
448  std::pair<size_t, size_t> FindHitMultiplet(size_t iHit) const;
449 
450  void CheckHitClusterAssociations();
451 
453  static bool areInSameMultiplet(recob::Hit const& first_hit, recob::Hit const& second_hit);
454 
455  }; // class ClusterCrawlerAlg
456 
457 } // namespace cluster
458 
459 #endif // ifndef CLUSTERCRAWLERALG_H
float fScaleF
scale factor from Tick/Wire to dx/du
std::vector< short > hitNear
float fAveChg
average charge at leading edge of cluster
std::vector< ClusterStore > tcl
the clusters we are creating
std::vector< std::pair< int, int > > WireHitRange
std::vector< float > fTimeDelta
max time difference for matching
struct of temporary 2D vertices (end points)
std::vector< float > fChgCut
charge difference cut for adding a hit to a cluster
std::vector< Vtx3Store > vtx3
the 3D vertices we are reconstructing
float clBeginChg
begin average charge
std::vector< unsigned short > fMinWirAfterSkip
std::vector< recob::Hit > GetHits()
Returns the collection of reconstructed hits.
Declaration of signal hit object.
int fDebugWire
set to the Begin Wire and Hit of a cluster to print
void PrintClusters()
The data type to uniquely identify a Plane.
Definition: geo_types.h:463
std::vector< ClusterStore > const & GetClusters() const
Returns a constant reference to the clusters found.
float clEndSlp
slope at the end (= US end = low wire number)
std::vector< unsigned short > fMaxWirSkip
max number of wires that can be skipped while crawling
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:211
std::vector< float > fMinAmp
expected minimum signal in each wire plane
Cluster finding and building.
std::vector< float > fMergeChgCut
max charge ratio for matching
float fHitErrFac
hit time error = fHitErrFac * hit RMS used for cluster fit
art::ServiceHandle< geo::Geometry const > geom
struct of temporary 3D vertices
float fAveHitWidth
average width (EndTick - StartTick) of hits
static geo::PlaneID DecodeCTP(CTP_t CTP)
float fHitMinAmp
< ignore hits with Amp < this value
int fDebugHit
out detailed information while crawling
std::vector< bool > fLACrawl
Crawl Large Angle clusters on pass?
std::vector< short > inClus
Hit used in cluster (-1 = obsolete, 0 = free)
unsigned int fLastWire
the last wire with a hit
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
float fChgNearWindow
window (ticks) for finding nearby charge
unsigned short fNumPass
number of passes over the hit collection
std::vector< recob::Hit > && YieldHits()
Returns (and loses) the collection of reconstructed hits.
std::vector< VtxStore > const & GetEndPoints() const
Returns a constant reference to the 2D end points found.
unsigned int fFirstWire
the first wire with a hit
float DeadWireCount(const TCSlice &slc, const TrajPoint &tp1, const TrajPoint &tp2)
Definition: Utils.cxx:2094
static CTP_t EncodeCTP(const geo::PlaneID &planeID)
unsigned int clEndWir
begin wire
float fVertex2DCut
2D vtx -> cluster matching cut (chisq/dof)
float fVertex3DCut
2D vtx -> 3D vtx matching cut (chisq/dof)
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:73
void MergeOverlap(std::string inFcnLabel, TCSlice &slc, const CTP_t &inCTP, bool prt)
Definition: TCShower.cxx:2371
unsigned short fLAClusMaxHitsFit
max hits fitted on a Large Angle cluster
std::string PrintHit(const TCHit &tch)
Definition: Utils.cxx:6344
std::vector< float > fKinkChiRat
General LArSoft Utilities.
std::vector< bool > fFindVertices
run vertexing code after clustering?
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:481
float clBeginSlp
begin slope (= DS end = high wire number)
Definition of data types for geometry description.
std::vector< unsigned short > fMaxHitsFit
Max number of hits fitted.
static CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
float clChisq
chisq of the current fit
bool clLA
using Large Angle crawling code
std::vector< recob::Hit > fHits
our version of the hits
std::vector< unsigned short > fMinHits
Min number of hits to make a cluster.
float clEndChg
end average charge
std::vector< float > chifits
fit chisq for monitoring kinks, etc
Contains all timing reference information for the detector.
std::vector< Vtx3Store > const & GetVertices() const
Returns a constant reference to the 3D vertices found.
unsigned int clBeginWir
begin wire
float fLAClusAngleCut
call Large Angle Clustering code if > 0
std::vector< bool > mergeAvailable
set true if hit is with HitMergeChiCut of a neighbor hit
float fClProjErrFac
cluster projection error factor
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
Definition: DataStructs.h:51
unsigned int fFirstHit
first hit used
float clBeginChgNear
nearby charge
std::vector< float > chgNear
charge near a cluster on each wire
std::vector< VtxStore > vtx
the endpoints we are reconstructing
bool fFindHammerClusters
look for hammer type clusters
std::vector< short > const & GetinClus() const
Returns (and loses) the collection of reconstructed hits.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
float clEndChgNear
nearby charge
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:399
std::vector< unsigned int > fcl2hits
vector of hits used in the cluster
float fChgSlp
slope of the charge vs wire
Namespace collecting geometry-related classes utilities.
art framework interface to geometry description
std::vector< geo::WireID > fFilteredWires
std::vector< unsigned short > fNHitsAve