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