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