LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
cluster::MergeClusterAlg Class Reference

#include "MergeClusterAlg.h"

Public Member Functions

 MergeClusterAlg (fhicl::ParameterSet const &pset)
 
void FindClusterEndPoints (art::PtrVector< recob::Hit > const &cluster, TVector2 const &centre, TVector2 const &direction, TVector2 &start, TVector2 &end) const
 
double FindClusterOverlap (TVector2 const &direction, TVector2 const &centre, TVector2 const &start1, TVector2 const &end1, TVector2 const &start2, TVector2 const &end2) const
 
double FindCrossingDistance (TVector2 const &direction1, TVector2 const &centre1, TVector2 const &direction2, TVector2 const &centre2) const
 
double FindMinSeparation (art::PtrVector< recob::Hit > const &cluster1, art::PtrVector< recob::Hit > const &cluster2) const
 
double FindProjectedWidth (TVector2 const &centre1, TVector2 const &start1, TVector2 const &end1, TVector2 const &centre2, TVector2 const &start2, TVector2 const &end2) const
 
double GlobalWire (geo::WireID const &wireID) const
 
TVector2 HitCoordinates (art::Ptr< recob::Hit > const &hit) const
 
int MergeClusters (std::vector< art::PtrVector< recob::Hit >> const &planeClusters, std::vector< art::PtrVector< recob::Hit >> &clusters) const
 
bool PassCuts (double angle, double crossingDistance, double projectedWidth, double separation, double longLength) const
 

Private Attributes

unsigned int fMinMergeClusterSize
 
double fMaxMergeSeparation
 
double fProjWidthThreshold
 
art::ServiceHandle< art::TFileService const > tfs
 
geo::WireReadoutGeom const * fWireReadoutGeom
 
std::map< int, int > trueClusterMap
 
TTree * fTree
 
double fAngle
 
double fEigenvalue
 
int fCluster1Size
 
int fCluster2Size
 
double fLength1
 
double fLength2
 
double fSeparation
 
double fCrossingDistance
 
double fProjectedWidth
 
double fOverlap
 
bool fTrueMerge
 

Detailed Description

Definition at line 38 of file MergeClusterAlg.h.

Constructor & Destructor Documentation

cluster::MergeClusterAlg::MergeClusterAlg ( fhicl::ParameterSet const &  pset)

Definition at line 19 of file MergeClusterAlg.cxx.

References fAngle, fCluster1Size, fCluster2Size, fCrossingDistance, fEigenvalue, fLength1, fLength2, fMaxMergeSeparation, fMinMergeClusterSize, fOverlap, fProjectedWidth, fProjWidthThreshold, fSeparation, fTree, fTrueMerge, Get, and tfs.

21 {
22  fMinMergeClusterSize = pset.get<int>("MinMergeClusterSize");
23  fMaxMergeSeparation = pset.get<double>("MaxMergeSeparation");
24  fProjWidthThreshold = pset.get<double>("ProjWidthThreshold");
25  fTree = tfs->make<TTree>("MatchingVariables", "MatchingVariables");
26  fTree->Branch("Angle", &fAngle);
27  fTree->Branch("Eigenvalue", &fEigenvalue);
28  fTree->Branch("Cluster1Size", &fCluster1Size);
29  fTree->Branch("Cluster2Size", &fCluster2Size);
30  fTree->Branch("Length1", &fLength1);
31  fTree->Branch("Length2", &fLength2);
32  fTree->Branch("Separation", &fSeparation);
33  fTree->Branch("CrossingDistance", &fCrossingDistance);
34  fTree->Branch("ProjectedWidth", &fProjectedWidth);
35  fTree->Branch("Overlap", &fOverlap);
36  fTree->Branch("TrueMerge", &fTrueMerge);
37 }
art::ServiceHandle< art::TFileService const > tfs
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
geo::WireReadoutGeom const * fWireReadoutGeom
unsigned int fMinMergeClusterSize

Member Function Documentation

void cluster::MergeClusterAlg::FindClusterEndPoints ( art::PtrVector< recob::Hit > const &  cluster,
TVector2 const &  centre,
TVector2 const &  direction,
TVector2 &  start,
TVector2 &  end 
) const

Find estimates of cluster start/end points

Definition at line 39 of file MergeClusterAlg.cxx.

References HitCoordinates().

Referenced by MergeClusters().

44 {
46 
47  std::map<double, TVector2> hitProjection;
48 
49  // Project all hits onto line to determine end points
50  for (auto& hit : cluster) {
51  TVector2 pos = HitCoordinates(hit) - centre;
52  hitProjection[direction * pos] = pos;
53  }
54 
55  // Project end points onto line which passes through centre of cluster
56  start = hitProjection.begin()->second.Proj(direction) + centre;
57  end = hitProjection.rbegin()->second.Proj(direction) + centre;
58 }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
Detector simulation of raw signals on wires.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit) const
double cluster::MergeClusterAlg::FindClusterOverlap ( TVector2 const &  direction,
TVector2 const &  centre,
TVector2 const &  start1,
TVector2 const &  end1,
TVector2 const &  start2,
TVector2 const &  end2 
) const

Calculates the overlap of the clusters on the line projected between them

Definition at line 60 of file MergeClusterAlg.cxx.

References tmp.

66 {
68 
69  double clusterOverlap = 0;
70 
71  // Project onto the average direction through both clusters
72  double s1 = (start1 - centre) * direction;
73  double e1 = (end1 - centre) * direction;
74  double s2 = (start2 - centre) * direction;
75  double e2 = (end2 - centre) * direction;
76 
77  // Make sure end > start
78  if (s1 > e1) {
79  std::cout << "s1>e1: " << s1 << " and " << e1 << std::endl;
80  double tmp = e1;
81  e1 = s1;
82  s1 = tmp;
83  }
84  if (s2 > e2) {
85  std::cout << "s1>e1: " << s1 << " and " << e1 << std::endl;
86  double tmp = e2;
87  e2 = s2;
88  s2 = tmp;
89  }
90 
91  // Find the overlap of the clusters on the centre line
92  if ((e1 > s2) && (e2 > s1)) clusterOverlap = std::min((e1 - s2), (e2 - s1));
93 
94  return clusterOverlap;
95 }
Float_t tmp
Definition: plot.C:35
double cluster::MergeClusterAlg::FindCrossingDistance ( TVector2 const &  direction1,
TVector2 const &  centre1,
TVector2 const &  direction2,
TVector2 const &  centre2 
) const

Finds the distance between the crossing point of the lines and the closest line centre

Definition at line 97 of file MergeClusterAlg.cxx.

Referenced by MergeClusters().

101 {
103 
104  // Find intersection point of two lines drawn through the centre of the clusters
105  double dcross = (direction1.X() * direction2.Y()) - (direction1.Y() * direction2.X());
106  TVector2 p = centre2 - centre1;
107  double pcrossd = (p.X() * direction2.Y()) - (p.Y() * direction2.X());
108  TVector2 crossing = centre1 + ((pcrossd / dcross) * direction1);
109 
110  // Get distance from this point to the clusters
111  return std::min((centre1 - crossing).Mod(), (centre2 - crossing).Mod());
112 }
double cluster::MergeClusterAlg::FindMinSeparation ( art::PtrVector< recob::Hit > const &  cluster1,
art::PtrVector< recob::Hit > const &  cluster2 
) const

Calculates the minimum separation between two clusters

Definition at line 114 of file MergeClusterAlg.cxx.

References HitCoordinates().

Referenced by MergeClusters().

116 {
118 
119  double minDistance = 99999.;
120 
121  // Loop over the two clusters to find the smallest distance
122  for (auto const& hit1 : cluster1) {
123  for (auto const& hit2 : cluster2) {
124 
125  TVector2 pos1 = HitCoordinates(hit1);
126  TVector2 pos2 = HitCoordinates(hit2);
127 
128  double distance = (pos1 - pos2).Mod();
129 
130  if (distance < minDistance) minDistance = distance;
131  }
132  }
133 
134  return minDistance;
135 }
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit) const
double cluster::MergeClusterAlg::FindProjectedWidth ( TVector2 const &  centre1,
TVector2 const &  start1,
TVector2 const &  end1,
TVector2 const &  centre2,
TVector2 const &  start2,
TVector2 const &  end2 
) const

Projects clusters parallel to the line which runs through their centres and finds the minimum containing width

Definition at line 137 of file MergeClusterAlg.cxx.

Referenced by MergeClusters().

143 {
145 
146  // Get the line running through the centre of the two clusters
147  TVector2 parallel = (centre2 - centre1).Unit();
148  TVector2 perpendicular = parallel.Rotate(TMath::Pi() / 2);
149 
150  // Project the cluster vector onto this perpendicular line
151  double s1 = (start1 - centre1) * perpendicular;
152  double e1 = (end1 - centre1) * perpendicular;
153  double s2 = (start2 - centre2) * perpendicular;
154  double e2 = (end2 - centre2) * perpendicular;
155 
156  // Find the width in each direction
157  double projectionStart = std::max(TMath::Abs(s1), TMath::Abs(s2));
158  double projectionEnd = std::max(TMath::Abs(e1), TMath::Abs(e2));
159 
160  return projectionStart + projectionEnd; // FIXME (KJK): Really? The width is the start + the end?
161 }
double cluster::MergeClusterAlg::GlobalWire ( geo::WireID const &  wireID) const

Find the global wire position

Definition at line 163 of file MergeClusterAlg.cxx.

References geo::CryostatID::Cryostat, fWireReadoutGeom, geo::WireGeo::GetCenter(), geo::kInduction, geo::WireReadoutGeom::Nwires(), geo::WireReadoutGeom::Plane(), geo::PlaneID::Plane, geo::WireReadoutGeom::SignalType(), geo::TPCID::TPC, geo::WireReadoutGeom::Wire(), geo::WireID::Wire, and geo::PlaneGeo::WireCoordinate().

Referenced by HitCoordinates().

164 {
166 
167  auto const wireCenter = fWireReadoutGeom->Wire(wireID).GetCenter();
168  geo::PlaneID const planeID{wireID.Cryostat, wireID.TPC % 2, wireID.Plane};
169 
170  if (fWireReadoutGeom->SignalType(wireID) == geo::kInduction) {
171  return fWireReadoutGeom->Plane(planeID).WireCoordinate(wireCenter);
172  }
173  return wireID.Wire + ((wireID.TPC / 2) * fWireReadoutGeom->Nwires(planeID));
174 }
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
Definition: WireGeo.h:219
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:704
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:195
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
geo::WireReadoutGeom const * fWireReadoutGeom
WireGeo const & Wire(WireID const &wireid) const
Returns the specified wire.
Signal from induction planes.
Definition: geo_types.h:147
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
TVector2 cluster::MergeClusterAlg::HitCoordinates ( art::Ptr< recob::Hit > const &  hit) const

Return the coordinates of this hit in global wire/tick space

Definition at line 176 of file MergeClusterAlg.cxx.

References GlobalWire(), recob::Hit::PeakTime(), and recob::Hit::WireID().

Referenced by FindClusterEndPoints(), FindMinSeparation(), and MergeClusters().

177 {
179  return TVector2(GlobalWire(hit->WireID()), hit->PeakTime());
180 }
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:226
double GlobalWire(geo::WireID const &wireID) const
int cluster::MergeClusterAlg::MergeClusters ( std::vector< art::PtrVector< recob::Hit >> const &  planeClusters,
std::vector< art::PtrVector< recob::Hit >> &  clusters 
) const

Merges clusters which lie along a straight line

Definition at line 182 of file MergeClusterAlg.cxx.

References art::PtrVector< T >::at(), FindClusterEndPoints(), FindCrossingDistance(), FindMinSeparation(), FindProjectedWidth(), fMaxMergeSeparation, fMinMergeClusterSize, HitCoordinates(), hits(), PassCuts(), and art::PtrVector< T >::size().

Referenced by cluster::BlurredClustering::produce().

185 {
187 
188  std::vector<unsigned int> mergedClusters;
189 
190  std::vector<art::PtrVector<recob::Hit>> oldClusters = planeClusters;
191 
192  // Sort the clusters by size
193  std::sort(oldClusters.begin(),
194  oldClusters.end(),
196  return a.size() > b.size();
197  });
198 
199  // Find the numbers of clusters above size threshold
200  unsigned int nclusters = 0;
201  for (auto& cluster : oldClusters)
202  if (cluster.size() >= fMinMergeClusterSize) ++nclusters;
203 
204  // Until all clusters are merged, create new clusters
205  bool mergedAllClusters = false;
206  while (!mergedAllClusters) {
207 
208  // New cluster
210 
211  // Put the largest unmerged cluster in this new cluster
212  for (unsigned int initCluster = 0; initCluster < oldClusters.size(); ++initCluster) {
213  if (oldClusters.at(initCluster).size() < fMinMergeClusterSize or
214  std::find(mergedClusters.begin(), mergedClusters.end(), initCluster) !=
215  mergedClusters.end())
216  continue;
217  cluster = oldClusters.at(initCluster);
218  mergedClusters.push_back(initCluster);
219  break;
220  }
221 
222  // Merge all aligned clusters to this
223  bool mergedAllToThisCluster = false;
224  while (!mergedAllToThisCluster) {
225 
226  // Look at all clusters and merge
227  int nadded = 0;
228  for (unsigned int trialCluster = 0; trialCluster < oldClusters.size(); ++trialCluster) {
229 
230  if (oldClusters.at(trialCluster).size() < fMinMergeClusterSize or
231  std::find(mergedClusters.begin(), mergedClusters.end(), trialCluster) !=
232  mergedClusters.end())
233  continue;
234 
235  // Calculate the PCA for each
236  TPrincipal *pca1 = new TPrincipal(2, ""), *pca2 = new TPrincipal(2, "");
237  double hits[2];
238  TVector2 pos;
239 
240  // Cluster centre
241  TVector2 chargePoint1 = TVector2(0, 0), chargePoint2 = TVector2(0, 0);
242  double totalCharge1 = 0, totalCharge2 = 0;
243 
244  for (auto& hit1 : cluster) {
245  pos = HitCoordinates(hit1);
246  hits[0] = pos.X();
247  hits[1] = pos.Y();
248  pca1->AddRow(hits);
249  chargePoint1 += hit1->Integral() * pos;
250  totalCharge1 += hit1->Integral();
251  }
252  for (auto& hit2 : oldClusters.at(trialCluster)) {
253  pos = HitCoordinates(hit2);
254  hits[0] = pos.X();
255  hits[1] = pos.Y();
256  pca2->AddRow(hits);
257  chargePoint2 += hit2->Integral() * pos;
258  totalCharge2 += hit2->Integral();
259  }
260 
261  pca1->MakePrincipals();
262  pca2->MakePrincipals();
263 
264  // Properties of these clusters
265  TVector2 direction1 =
266  TVector2((*pca1->GetEigenVectors())[0][0], (*pca1->GetEigenVectors())[1][0]).Unit();
267  TVector2 direction2 =
268  TVector2((*pca2->GetEigenVectors())[0][0], (*pca2->GetEigenVectors())[1][0]).Unit();
269  TVector2 direction = ((direction1 + direction2) / 2).Unit();
270  TVector2 centre1 = chargePoint1 / totalCharge1;
271  TVector2 centre2 = chargePoint2 / totalCharge2;
272  TVector2 centre = (centre1 + centre2) / 2;
273  TVector2 start1, end1;
274  TVector2 start2, end2;
275  FindClusterEndPoints(cluster, centre1, direction1, start1, end1);
276  FindClusterEndPoints(oldClusters.at(trialCluster), centre2, direction2, start2, end2);
277  double length1 = (end1 - start1).Mod();
278  double length2 = (end2 - start2).Mod();
279 
280  // Properties of the pair of clusters
281  double crossingDistance = FindCrossingDistance(direction1, centre1, direction2, centre2);
282  double projectedWidth = FindProjectedWidth(centre1, start1, end1, centre2, start2, end2);
283  double angle = direction1.DeltaPhi(direction2);
284  if (angle > 1.57) angle = 3.14159 - angle;
285  double separation = FindMinSeparation(cluster, oldClusters.at(trialCluster));
286 
287  if (separation > fMaxMergeSeparation) continue;
288  if (PassCuts(
289  angle, crossingDistance, projectedWidth, separation, TMath::Max(length1, length2))) {
290 
291  for (auto& hit : oldClusters.at(trialCluster))
292  cluster.push_back(hit);
293 
294  mergedClusters.push_back(trialCluster);
295  ++nadded;
296  }
297 
298  delete pca1;
299  delete pca2;
300 
301  } // loop over clusters to add
302 
303  if (nadded == 0) mergedAllToThisCluster = true;
304 
305  } // while loop
306 
307  clusters.push_back(cluster);
308  if (mergedClusters.size() == nclusters) mergedAllClusters = true;
309  }
310 
311  return clusters.size();
312 }
void FindClusterEndPoints(art::PtrVector< recob::Hit > const &cluster, TVector2 const &centre, TVector2 const &direction, TVector2 &start, TVector2 &end) const
Cluster finding and building.
void hits()
Definition: readHits.C:15
reference at(size_type n)
Definition: PtrVector.h:359
size_type size() const
Definition: PtrVector.h:302
Detector simulation of raw signals on wires.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit) const
double FindMinSeparation(art::PtrVector< recob::Hit > const &cluster1, art::PtrVector< recob::Hit > const &cluster2) const
double FindCrossingDistance(TVector2 const &direction1, TVector2 const &centre1, TVector2 const &direction2, TVector2 const &centre2) const
bool PassCuts(double angle, double crossingDistance, double projectedWidth, double separation, double longLength) const
double FindProjectedWidth(TVector2 const &centre1, TVector2 const &start1, TVector2 const &end1, TVector2 const &centre2, TVector2 const &start2, TVector2 const &end2) const
unsigned int fMinMergeClusterSize
bool cluster::MergeClusterAlg::PassCuts ( double  angle,
double  crossingDistance,
double  projectedWidth,
double  separation,
double  longLength 
) const

Boolean function which decides whether or not two clusters should be merged, depending on their properties

Definition at line 314 of file MergeClusterAlg.cxx.

References fProjWidthThreshold.

Referenced by MergeClusters().

319 {
321 
322  bool passCrossingDistanceAngle = false;
323  if (crossingDistance < (-2 + (5 / (1 * TMath::Abs(angle)) - 0))) passCrossingDistanceAngle = true;
324 
325  bool passSeparationAngle = false;
326  if (separation < (200 * TMath::Abs(angle) + 40)) passSeparationAngle = true;
327 
328  bool passProjectedWidth = false;
329  if (((double)projectedWidth / (double)longLength) < fProjWidthThreshold)
330  passProjectedWidth = true;
331 
332  return passCrossingDistanceAngle and passSeparationAngle and passProjectedWidth;
333 }

Member Data Documentation

double cluster::MergeClusterAlg::fAngle
private

Definition at line 91 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

int cluster::MergeClusterAlg::fCluster1Size
private

Definition at line 93 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

int cluster::MergeClusterAlg::fCluster2Size
private

Definition at line 94 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fCrossingDistance
private

Definition at line 98 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fEigenvalue
private

Definition at line 92 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fLength1
private

Definition at line 95 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fLength2
private

Definition at line 96 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fMaxMergeSeparation
private

Definition at line 79 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg(), and MergeClusters().

unsigned int cluster::MergeClusterAlg::fMinMergeClusterSize
private

Definition at line 78 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg(), and MergeClusters().

double cluster::MergeClusterAlg::fOverlap
private

Definition at line 100 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fProjectedWidth
private

Definition at line 99 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

double cluster::MergeClusterAlg::fProjWidthThreshold
private

Definition at line 81 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg(), and PassCuts().

double cluster::MergeClusterAlg::fSeparation
private

Definition at line 97 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

TTree* cluster::MergeClusterAlg::fTree
private

Definition at line 90 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

bool cluster::MergeClusterAlg::fTrueMerge
private

Definition at line 101 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

geo::WireReadoutGeom const* cluster::MergeClusterAlg::fWireReadoutGeom
private

Definition at line 85 of file MergeClusterAlg.h.

Referenced by GlobalWire().

art::ServiceHandle<art::TFileService const> cluster::MergeClusterAlg::tfs
private

Definition at line 84 of file MergeClusterAlg.h.

Referenced by MergeClusterAlg().

std::map<int, int> cluster::MergeClusterAlg::trueClusterMap
private

Definition at line 87 of file MergeClusterAlg.h.


The documentation for this class was generated from the following files: