SimpleClustering.cxx
Go to the documentation of this file.
1 /**
2  * @file SimpleClustering.cxx
3  *
4  * @author D.Stefan and R.Sulej
5  *
6  * @brief Collect hits "touching" each other (next wire or consecutive ticks).
7  */
8 
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) fHits.push_back(hits[h]);
16 }
17 // ------------------------------------------------------
18 
20 {
21  const tss::Hit2D* hit = 0;
22  if (idx < fHits.size())
23  {
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  {
36  fHits.erase(fHits.begin() + h); 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  {
50  d = pma::Dist2(fHits[h]->Point2D(), p2d);
51  if (d < dmin) { dmin = d; hout = fHits[h]; idx = h; }
52  }
53  return hout;
54 }
55 // ------------------------------------------------------
56 
57 const tss::Hit2D* tss::Cluster2D::outermost(size_t & idx) const
58 {
59  idx = 0;
60  if (!fHits.size()) return 0;
61 
62  TVector2 mean(0., 0.);
63  for (size_t h = 0; h < fHits.size(); ++h)
64  {
65  mean += fHits[h]->Point2D();
66  }
67  mean *= 1.0 / fHits.size();
68 
69  const tss::Hit2D* hout = fHits.front();
70  double d, dmax = pma::Dist2(hout->Point2D(), mean);
71  for (size_t h = 1; h < fHits.size(); ++h)
72  {
73  d = pma::Dist2(fHits[h]->Point2D(), mean);
74  if (d > dmax) { dmax = d; hout = fHits[h]; idx = h; }
75  }
76  return hout;
77 }
78 // ------------------------------------------------------
79 
80 const TVector2 tss::Cluster2D::min(void) const
81 {
82 
83  TVector2 minimum = fHits[0]->Point2D();
84 
85  for (size_t i = 1; i < size(); ++i)
86  {
87  const TVector2 h = fHits[i]->Point2D();
88 
89  if (h.X() < minimum.X()) minimum.Set(h.X(), h.Y());
90  if (h.Y() < minimum.Y()) minimum.Set(minimum.X(), h.Y());
91  }
92 
93  return minimum;
94 }
95 
96 // ------------------------------------------------------
97 
98 const TVector2 tss::Cluster2D::max(void) const
99 {
100 
101  TVector2 maximum = fHits[0]->Point2D();
102 
103  for (size_t i = 1; i < size(); ++i)
104  {
105  const TVector2 h = fHits[i]->Point2D();
106 
107  if (h.X() > maximum.X()) maximum.Set(h.X(), h.Y());
108  if (h.Y() > maximum.Y()) maximum.Set(maximum.X(), h.Y());
109  }
110 
111  return maximum;
112 }
113 
114 // ------------------------------------------------------
115 
117 {
118  for (size_t i = 0; i < fHits.size(); ++i)
119  if (fHits[i] == hit) return true;
120  return false;
121 }
122 // ------------------------------------------------------
123 
124 double tss::Cluster2D::dist2(const TVector2 & p2d) const
125 {
126  if (fHits.size())
127  {
128  double d2, min_d2 = pma::Dist2(fHits.front()->Point2D(), p2d);
129  for (size_t i = 1; i < fHits.size(); ++i)
130  {
131  d2 = pma::Dist2(fHits[i]->Point2D(), p2d);
132  if (d2 < min_d2) { min_d2 = d2; }
133  }
134  return min_d2;
135  }
136  else return 0.0;
137 }
138 // ------------------------------------------------------
139 
140 double tss::Cluster2D::dist2(const TVector2 & p2d, size_t & hIdx) const
141 {
142  hIdx = 0;
143  if (fHits.size())
144  {
145  double d2, min_d2 = pma::Dist2(fHits.front()->Point2D(), p2d);
146  for (size_t i = 1; i < fHits.size(); ++i)
147  {
148  d2 = pma::Dist2(fHits[i]->Point2D(), p2d);
149  if (d2 < min_d2) { min_d2 = d2; hIdx = i; }
150  }
151  return min_d2;
152  }
153  else return 0.0;
154 }
155 // ------------------------------------------------------
156 
157 double tss::Cluster2D::dist2(const tss::Cluster2D & clu) const
158 {
159  if (fHits.size())
160  {
161  double d2, min_d2 = clu.dist2(fHits.front()->Point2D());
162  for (size_t i = 1; i < fHits.size(); ++i)
163  {
164  d2 = clu.dist2(fHits[i]->Point2D());
165  if (d2 < min_d2) { min_d2 = d2; }
166  }
167  return min_d2;
168  }
169  else return 0.0;
170 }
171 // ------------------------------------------------------
172 
173 // ------------------------------------------------------
174 // ------------------------------------------------------
175 // ------------------------------------------------------
176 
177 
179 {
180  if ((h1.Wire() == h2.Wire()) &&
181  (h1.PeakTime() == h2.PeakTime())) return false;
182 
183  bool touches = false;
184  if ((h1.Wire() >= h2.Wire() - 1) &&
185  (h1.Wire() <= h2.Wire() + 1))
186  {
187  if (((h2.StartTick() <= h1.StartTick()) && (h1.StartTick() <= h2.EndTick() + 1)) ||
188  ((h2.StartTick() <= h1.EndTick() + 1) && (h1.EndTick() <= h2.EndTick())) ||
189  ((h2.StartTick() >= h1.StartTick()) && (h1.EndTick() >= h2.EndTick())))
190  {
191  touches = true;
192  }
193  }
194  return touches;
195 }
196 // ------------------------------------------------------
197 
199 {
200  for (size_t i = 0; i < c1.size(); i++)
201  {
202  if (hitsTouching(c1[i], h2)) return true;
203  }
204  return false;
205 }
206 // ------------------------------------------------------
207 
209 {
210  for (unsigned int i = 0; i < c1.size(); i++)
211  {
212  if (hitsTouching(c2, c1[i])) return true;
213  }
214  return false;
215 }
216 // ------------------------------------------------------
217 
218 void tss::SimpleClustering::merge(std::vector< tss::Cluster2D > & clusters) const
219 {
220  bool merged = true;
221  while (merged)
222  {
223  merged = false;
224 
225  size_t i = 0;
226  while (i < clusters.size() - 1)
227  {
228  size_t j = i + 1;
229  while (j < clusters.size())
230  {
231  if (hitsTouching(clusters[i], clusters[j]))
232  {
233  clusters[i].hits().reserve(clusters[i].size() + clusters[i].size());
234  for (size_t h = 0; h < clusters[j].size(); ++h)
235  clusters[i].hits().push_back(clusters[j].hits()[h]);
236  clusters.erase(clusters.begin() + j);
237  merged = true;
238  }
239  else ++j;
240  }
241  ++i;
242  }
243  }
244 }
245 // ------------------------------------------------------
246 
247 std::vector< tss::Cluster2D > tss::SimpleClustering::run(const std::vector< tss::Hit2D > & inp) const
248 {
249  std::vector< tss::Cluster2D > result;
250  for (size_t h = 0; h < inp.size(); ++h)
251  {
252  bool found = false;
253  for (size_t r = 0; r < result.size(); ++r)
254  if (hitsTouching(result[r], inp[h]))
255  {
256  result[r].hits().push_back(&(inp[h])); found = true; break;
257  }
258  if (!found)
259  {
260  result.push_back(tss::Cluster2D());
261  result.back().hits().push_back(&(inp[h]));
262  }
263  }
264  merge(result);
265 
266  return result;
267 }
268 // ------------------------------------------------------
269 
270 std::vector< tss::Cluster2D > tss::SimpleClustering::run(const tss::Cluster2D & inp) const
271 {
272  std::vector< tss::Cluster2D > result;
273  for (size_t h = 0; h < inp.size(); ++h)
274  {
275  bool found = false;
276  for (size_t r = 0; r < result.size(); ++r)
277  if (hitsTouching(result[r], inp[h]))
278  {
279  result[r].hits().push_back(inp.hits()[h]); found = true; break;
280  }
281  if (!found)
282  {
283  result.push_back(tss::Cluster2D());
284  result.back().hits().push_back(inp.hits()[h]);
285  }
286  }
287  merge(result);
288 
289  return result;
290 }
291 // ------------------------------------------------------
TVector2 const & Point2D() const
Definition: TssHit2D.h:36
static QCString result
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:37
unsigned int Wire() const
Definition: TssHit2D.h:57
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
int StartTick() const
Definition: TssHit2D.h:67
std::vector< tss::Cluster2D > run(const std::vector< tss::Hit2D > &inp) const
void merge(std::vector< tss::Cluster2D > &clusters) const
const Hit2D * release_at(size_t idx)
float PeakTime() const
Definition: TssHit2D.h:62
Detector simulation of raw signals on wires.
bool hitsTouching(const tss::Hit2D &h1, const tss::Hit2D &h2) const
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:72
bool has(const tss::Hit2D *hit) const
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
size_t size(void) const