LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
SimpleClustering.cxx
Go to the documentation of this file.
1 
9 #include "SimpleClustering.h"
10 
12 
13 tss::Cluster2D::Cluster2D(const std::vector< const tss::Hit2D* > & hits) :
14  fDenseStart(false), fDenseEnd(false), fIsEM(false)
15 {
16  fHits.reserve(hits.size());
17  for (size_t h = 0; h < hits.size(); ++h) fHits.push_back(hits[h]);
18 }
19 // ------------------------------------------------------
20 
22 {
23  const tss::Hit2D* hit = 0;
24  if (idx < fHits.size())
25  {
26  hit = fHits[idx];
27  fHits.erase(fHits.begin() + idx);
28  }
29  return hit;
30 }
31 // ------------------------------------------------------
32 
34 {
35  for (size_t h = 0; h < fHits.size(); ++h)
36  if (fHits[h] == hit)
37  {
38  fHits.erase(fHits.begin() + h); return true;
39  }
40  return false;
41 }
42 
43 const tss::Hit2D* tss::Cluster2D::closest(const TVector2 & p2d, size_t & idx) const
44 {
45  idx = 0;
46  if (!fHits.size()) return 0;
47 
48  const tss::Hit2D* hout = fHits.front();
49  double d, dmin = pma::Dist2(hout->Point2D(), p2d);
50  for (size_t h = 1; h < fHits.size(); ++h)
51  {
52  d = pma::Dist2(fHits[h]->Point2D(), p2d);
53  if (d < dmin) { dmin = d; hout = fHits[h]; idx = h; }
54  }
55  return hout;
56 }
57 // ------------------------------------------------------
58 
59 const tss::Hit2D* tss::Cluster2D::outermost(size_t & idx) const
60 {
61  idx = 0;
62  if (!fHits.size()) return 0;
63 
64  TVector2 mean(0., 0.);
65  for (size_t h = 0; h < fHits.size(); ++h)
66  {
67  mean += fHits[h]->Point2D();
68  }
69  mean *= 1.0 / fHits.size();
70 
71  const tss::Hit2D* hout = fHits.front();
72  double d, dmax = pma::Dist2(hout->Point2D(), mean);
73  for (size_t h = 1; h < fHits.size(); ++h)
74  {
75  d = pma::Dist2(fHits[h]->Point2D(), mean);
76  if (d > dmax) { dmax = d; hout = fHits[h]; idx = h; }
77  }
78  return hout;
79 }
80 // ------------------------------------------------------
81 
82 const TVector2 tss::Cluster2D::min(void) const
83 {
84 
85  TVector2 minimum = fHits[0]->Point2D();
86 
87  for (size_t i = 1; i < size(); ++i)
88  {
89  const TVector2 h = fHits[i]->Point2D();
90 
91  if (h.X() < minimum.X()) minimum.Set(h.X(), h.Y());
92  if (h.Y() < minimum.Y()) minimum.Set(minimum.X(), h.Y());
93  }
94 
95  return minimum;
96 }
97 
98 // ------------------------------------------------------
99 
100 const TVector2 tss::Cluster2D::max(void) const
101 {
102 
103  TVector2 maximum = fHits[0]->Point2D();
104 
105  for (size_t i = 1; i < size(); ++i)
106  {
107  const TVector2 h = fHits[i]->Point2D();
108 
109  if (h.X() > maximum.X()) maximum.Set(h.X(), h.Y());
110  if (h.Y() > maximum.Y()) maximum.Set(maximum.X(), h.Y());
111  }
112 
113  return maximum;
114 }
115 
116 // ------------------------------------------------------
117 
119 {
120  for (size_t i = 0; i < fHits.size(); ++i)
121  if (fHits[i] == hit) return true;
122  return false;
123 }
124 // ------------------------------------------------------
125 
126 double tss::Cluster2D::dist2(const TVector2 & p2d) const
127 {
128  if (fHits.size())
129  {
130  double d2, min_d2 = pma::Dist2(fHits.front()->Point2D(), p2d);
131  for (size_t i = 1; i < fHits.size(); ++i)
132  {
133  d2 = pma::Dist2(fHits[i]->Point2D(), p2d);
134  if (d2 < min_d2) { min_d2 = d2; }
135  }
136  return min_d2;
137  }
138  else return 0.0;
139 }
140 // ------------------------------------------------------
141 
142 double tss::Cluster2D::dist2(const TVector2 & p2d, size_t & hIdx) const
143 {
144  hIdx = 0;
145  if (fHits.size())
146  {
147  double d2, min_d2 = pma::Dist2(fHits.front()->Point2D(), p2d);
148  for (size_t i = 1; i < fHits.size(); ++i)
149  {
150  d2 = pma::Dist2(fHits[i]->Point2D(), p2d);
151  if (d2 < min_d2) { min_d2 = d2; hIdx = i; }
152  }
153  return min_d2;
154  }
155  else return 0.0;
156 }
157 // ------------------------------------------------------
158 
159 double tss::Cluster2D::dist2(const tss::Cluster2D & clu) const
160 {
161  if (fHits.size())
162  {
163  double d2, min_d2 = clu.dist2(fHits.front()->Point2D());
164  for (size_t i = 1; i < fHits.size(); ++i)
165  {
166  d2 = clu.dist2(fHits[i]->Point2D());
167  if (d2 < min_d2) { min_d2 = d2; }
168  }
169  return min_d2;
170  }
171  else return 0.0;
172 }
173 // ------------------------------------------------------
174 
175 // ------------------------------------------------------
176 // ------------------------------------------------------
177 // ------------------------------------------------------
178 
179 
181 {
182  if ((h1.Wire() == h2.Wire()) &&
183  (h1.PeakTime() == h2.PeakTime())) return false;
184 
185  bool touches = false;
186  if ((h1.Wire() >= h2.Wire() - 1) &&
187  (h1.Wire() <= h2.Wire() + 1))
188  {
189  if (((h2.StartTick() <= h1.StartTick()) && (h1.StartTick() <= h2.EndTick() + 1)) ||
190  ((h2.StartTick() <= h1.EndTick() + 1) && (h1.EndTick() <= h2.EndTick())) ||
191  ((h2.StartTick() >= h1.StartTick()) && (h1.EndTick() >= h2.EndTick())))
192  {
193  touches = true;
194  }
195  }
196  return touches;
197 }
198 // ------------------------------------------------------
199 
201 {
202  for (size_t i = 0; i < c1.size(); i++)
203  {
204  if (hitsTouching(c1[i], h2)) return true;
205  }
206  return false;
207 }
208 // ------------------------------------------------------
209 
211 {
212  for (unsigned int i = 0; i < c1.size(); i++)
213  {
214  if (hitsTouching(c2, c1[i])) return true;
215  }
216  return false;
217 }
218 // ------------------------------------------------------
219 
220 void tss::SimpleClustering::merge(std::vector< tss::Cluster2D > & clusters) const
221 {
222  bool merged = true;
223  while (merged)
224  {
225  merged = false;
226 
227  size_t i = 0;
228  while (i < clusters.size() - 1)
229  {
230  size_t j = i + 1;
231  while (j < clusters.size())
232  {
233  if (hitsTouching(clusters[i], clusters[j]))
234  {
235  clusters[i].hits().reserve(clusters[i].size() + clusters[i].size());
236  for (size_t h = 0; h < clusters[j].size(); ++h)
237  clusters[i].hits().push_back(clusters[j].hits()[h]);
238  clusters.erase(clusters.begin() + j);
239  merged = true;
240  }
241  else ++j;
242  }
243  ++i;
244  }
245  }
246 }
247 // ------------------------------------------------------
248 
249 std::vector< tss::Cluster2D > tss::SimpleClustering::run(const std::vector< tss::Hit2D > & inp) const
250 {
251  std::vector< tss::Cluster2D > result;
252  for (size_t h = 0; h < inp.size(); ++h)
253  {
254  bool found = false;
255  for (size_t r = 0; r < result.size(); ++r)
256  if (hitsTouching(result[r], inp[h]))
257  {
258  result[r].hits().push_back(&(inp[h])); found = true; break;
259  }
260  if (!found)
261  {
262  result.push_back(tss::Cluster2D());
263  result.back().hits().push_back(&(inp[h]));
264  }
265  }
266  merge(result);
267 
268  return result;
269 }
270 // ------------------------------------------------------
271 
272 std::vector< tss::Cluster2D > tss::SimpleClustering::run(const tss::Cluster2D & inp) const
273 {
274  std::vector< tss::Cluster2D > result;
275  for (size_t h = 0; h < inp.size(); ++h)
276  {
277  bool found = false;
278  for (size_t r = 0; r < result.size(); ++r)
279  if (hitsTouching(result[r], inp[h]))
280  {
281  result[r].hits().push_back(inp.hits()[h]); found = true; break;
282  }
283  if (!found)
284  {
285  result.push_back(tss::Cluster2D());
286  result.back().hits().push_back(inp.hits()[h]);
287  }
288  }
289  merge(result);
290 
291  return result;
292 }
293 // ------------------------------------------------------
294 
TVector2 const & Point2D(void) const
Definition: TssHit2D.h:37
Trivial, collect hits "touching" each other (next wire or consecutive ticks), plus Cluster2D class to...
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
unsigned int Wire(void) const
Definition: TssHit2D.h:42
float PeakTime(void) const
Definition: TssHit2D.h:43
std::vector< const tss::Hit2D * > fHits
const Hit2D * outermost(size_t &idx) const
double dist2(const TVector2 &p2d) const
const Hit2D * closest(const TVector2 &p2d, size_t &idx) const
const std::vector< const tss::Hit2D * > & hits(void) const
void hits()
Definition: readHits.C:15
TCanvas * c1
Definition: plotHisto.C:7
TCanvas * c2
Definition: plot_hist.C:75
std::vector< tss::Cluster2D > run(const std::vector< tss::Hit2D > &inp) const
void merge(std::vector< tss::Cluster2D > &clusters) const
Float_t d
Definition: plot.C:237
const Hit2D * release_at(size_t idx)
Detector simulation of raw signals on wires.
TH1F * h2
Definition: plot.C:46
bool hitsTouching(const tss::Hit2D &h1, const tss::Hit2D &h2) const
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:15
bool release(const tss::Hit2D *hit)
const TVector2 max(void) const
void merge(tss::Cluster2D &clu)
const TVector2 min(void) const
TH1F * h1
Definition: plot.C:43
bool has(const tss::Hit2D *hit) const
size_t size(void) const
int EndTick(void) const
Definition: TssHit2D.h:45
int StartTick(void) const
Definition: TssHit2D.h:44