LArSoft  v10_04_05
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 
20 // LArSoft libraries
26 namespace detinfo {
27  class DetectorClocksData;
28  class DetectorPropertiesData;
29 }
30 
31 namespace cluster {
32 
34  public:
35  // some functions to handle the CTP_t type
36  typedef unsigned int CTP_t;
37 
38  static constexpr unsigned int CTPpad = 1000; // alignment for CTP sub-items
39  static CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
40  {
41  return cryo * CTPpad * CTPpad + tpc * CTPpad + plane;
42  }
43  static CTP_t EncodeCTP(const geo::PlaneID& planeID)
44  {
45  return EncodeCTP(planeID.Cryostat, planeID.TPC, planeID.Plane);
46  }
47  static geo::PlaneID DecodeCTP(CTP_t CTP)
48  {
49  return {CTP / (CTPpad * CTPpad), CTP / CTPpad % CTPpad, CTP % CTPpad};
50  }
51 
54 
56  struct ClusterStore {
57  short ID; // Cluster ID. ID < 0 = abandoned cluster
58  short ProcCode; // Processor code for debugging
59  short StopCode; // code for the reason for stopping cluster tracking
60  CTP_t CTP; // Cryostat/TPC/Plane code
61  float BeginSlp; // beginning slope (= DS end = high wire number)
62  float BeginSlpErr; // error
63  float BeginAng;
64  unsigned int BeginWir; // begin wire
65  float BeginTim; // begin time
66  float BeginChg; // beginning average charge
67  float BeginChgNear; // charge near the cluster Begin
68  short BeginVtx; // ID of the Begin vertex
69  float EndSlp; // end slope (= US end = low wire number)
70  float EndAng;
71  float EndSlpErr; // error
72  unsigned int EndWir; // end wire
73  float EndTim; // ending time
74  float EndChg; // ending average charge
75  float EndChgNear; // charge near the cluster End
76  short EndVtx; // ID of the end vertex
77  std::vector<unsigned int> tclhits; // hits on the cluster
78  }; // ClusterStore
79 
81  struct VtxStore {
82  float Wire;
83  float WireErr;
84  float Time;
85  float TimeErr;
86  unsigned short NClusters; // = 0 for abandoned vertices
87  float ChiDOF;
88  short Topo; // 1 = US-US, 2 = US-DS, 3 = DS-US, 4 = DS-DS, 5 = Star,
89  // 6 = hammer, 7 = vtx3clustermatch, 8 = vtx3clustersplit, 9 = FindTrajVertices
90  CTP_t CTP;
91  bool Fixed; // Vertex position fixed (should not be re-fit)
92  };
93 
95  struct Vtx3Store {
96  std::array<short, 3> Ptr2D; // pointers to 2D vertices in each plane
97  float X; // x position
98  float XErr; // x position error
99  float Y; // y position
100  float YErr; // y position error
101  float Z; // z position
102  float ZErr; // z position error
103  short Wire; // wire number for an incomplete 3D vertex
104  unsigned short CStat;
105  unsigned short TPC;
106  unsigned short ProcCode;
107  };
108 
109  explicit ClusterCrawlerAlg(fhicl::ParameterSet const& pset);
110 
111  void RunCrawler(detinfo::DetectorClocksData const& clock_data,
112  detinfo::DetectorPropertiesData const& det_prop,
113  std::vector<recob::Hit> const& srchits);
114 
117 
118  std::vector<short> const& GetinClus() const { return inClus; }
119 
121  std::vector<recob::Hit>&& YieldHits() { return std::move(fHits); }
122 
124  std::vector<recob::Hit> GetHits() { return fHits; }
125 
127  std::vector<ClusterStore> const& GetClusters() const { return tcl; }
128 
130  std::vector<VtxStore> const& GetEndPoints() const { return vtx; }
131 
133  std::vector<Vtx3Store> const& GetVertices() const { return vtx3; }
134 
137  void ClearResults();
138 
140 
142  static bool SortByMultiplet(recob::Hit const& a, recob::Hit const& b);
143 
145 
146  private:
147  unsigned short fNumPass;
148  std::vector<unsigned short> fMaxHitsFit;
149  std::vector<unsigned short> fMinHits;
150  std::vector<unsigned short> fNHitsAve;
151  std::vector<float> fChiCut;
153  std::vector<float> fKinkChiRat;
154  std::vector<float> fKinkAngCut;
156  std::vector<float> fChgCut;
157  std::vector<unsigned short>
159  std::vector<unsigned short> fMinWirAfterSkip;
160  std::vector<bool> fDoMerge;
162  std::vector<float> fTimeDelta;
163  std::vector<float> fMergeChgCut;
164  std::vector<bool> fFindVertices;
165  std::vector<bool> fLACrawl;
167  // bool fFindVLAClusters; ///< look for Very Large Angle clusters
169 
170  std::vector<float> fMinAmp;
171 
176  // bool fFindTrajVertices;
177 
178  // global cuts and parameters
179  float fHitErrFac;
180  float fHitMinAmp;
182  float fMinHitFrac;
184  unsigned short fLAClusMaxHitsFit;
188  float fMergeOverlapAngCut;
190  unsigned short fAllowNoHitWire;
191  float fVertex2DCut;
193  float fVertex3DCut;
194 
197  int fDebugHit;
198 
199  // Wires that have been determined by some filter (e.g. NoiseFilter) to be good
200  std::vector<geo::WireID> fFilteredWires;
201 
202  // these variables define the cluster used during crawling
203  float clpar[3];
204  float clparerr[2];
206  float clChisq;
207  float fAveChg;
208  // float fChgRMS; ///< average charge RMS at leading edge of cluster
209  float fChgSlp;
210  float fAveHitWidth;
211 
212  bool prt;
213  bool vtxprt;
214  unsigned short NClusters;
215 
217  geo::WireReadoutGeom const* wireReadoutGeom{
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:364
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:195
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
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:2095
static CTP_t EncodeCTP(const geo::PlaneID &planeID)
unsigned int clEndWir
begin wire
float fVertex2DCut
2D vtx -> cluster matching cut (chisq/dof)
Interface for a class providing readout channel mapping to geometry.
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:6347
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:306
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
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:49
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:315
std::vector< unsigned int > fcl2hits
vector of hits used in the cluster
float fChgSlp
slope of the charge vs wire
art framework interface to geometry description
std::vector< geo::WireID > fFilteredWires
std::vector< unsigned short > fNHitsAve