Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
JAlgorithm.hh
Go to the documentation of this file.
1#ifndef __JTRIGGER__JALGORITHM__
2#define __JTRIGGER__JALGORITHM__
3
4#include <vector>
5#include <algorithm>
6#include <iterator>
7
8
9/**
10 * \file
11 *
12 * Algorithms for hit clustering and sorting.
13 * \author mdejong
14 */
15namespace JTRIGGER {}
16namespace JPP { using namespace JTRIGGER; }
17
18namespace JTRIGGER {
19
20 /**
21 * Anonymous structure for clustering of hits.
22 */
23 static const struct clusterize {
24
25 /**
26 * Partition data according given binary match operator.
27 *
28 * The underlying algorithm is known in literature as 'clique'.
29 * The result is (likely to be) the maximal sub-set with all elements matched to each other.
30 * The complexity is quadratic, i.e.\ at most (number of elements x number of elements) operations.
31 * The algorithm will sort the data such that all clusterized hits are at the front.
32 * The return value points the first non clusterized hit.
33 *
34 * The hit iterator refers to a data structure which should conform with the match operator.
35 *
36 * \param __begin begin of data
37 * \param __end end of data
38 * \param match binary match operator
39 * \param Nmin minimum cluster size
40 * \return end of data
41 */
42 template<class JHitIterator_t, class JMatch_t>
43 inline JHitIterator_t operator()(JHitIterator_t __begin,
44 JHitIterator_t __end,
45 const JMatch_t& match,
46 const int Nmin = 1) const
47 {
48 return (*this)(__begin, std::distance(__begin,__end), match, Nmin, typename std::iterator_traits<JHitIterator_t>::iterator_category());
49 }
50
51
52 /**
53 * Select best root hit according given comparator and partition remaining data
54 * according given binary match operator and this root hit.
55 * The complexity is linear, i.e.\ at most number of elements operations.
56 * The algorithm will sort the data such that all selected hits are at the front.
57 *
58 * \param __begin begin of data
59 * \param __end end of data
60 * \param comparator comparator
61 * \param match binary match operator
62 * \return end of data
63 */
64 template<class JHitIterator_t, class JComparator_t, class JMatch_t>
65 inline JHitIterator_t operator()(JHitIterator_t __begin,
66 JHitIterator_t __end,
67 const JComparator_t& comparator,
68 const JMatch_t& match) const
69 {
70 if (__begin != __end) {
71
72 std::sort(__begin, __end, comparator);
73
74 JHitIterator_t root = __begin;
75
76 return std::partition(++__begin, __end, JBind2nd(match, *root));
77
78 } else {
79
80 return __end;
81 }
82 }
83
84 private:
85 /**
86 * Implementation of method clusterize for random access iterators.
87 *
88 * \param buffer pointer to data
89 * \param N number of hits
90 * \param match binary match operator
91 * \param Nmin minimum cluster size
92 * \param tag iterator tag
93 * \return pointer to end of data
94 */
95 template<class JHitIterator_t, class JMatch_t>
96 inline JHitIterator_t operator()(JHitIterator_t buffer,
97 const int N,
98 const JMatch_t& match,
99 const int Nmin,
100 std::random_access_iterator_tag tag) const
101 {
102 using namespace std;
103
104 if (N >= Nmin) {
105
106 int i, j;
107 int n = N;
108
109 // Determine number of associated hits for each hit.
110
111 count.resize(N);
112
113 for (vector<int>::iterator __i = count.begin(); __i != count.end(); ++__i) {
114 *__i = 1; // Assume always a match with itself.
115 }
116
117 for (i = 0; i != N; ++i) {
118 for (j = i; ++j != N; ) {
119 if (match(buffer[i], buffer[j])) {
120 ++count[i];
121 ++count[j];
122 }
123 }
124 }
125
126 // Remove hit with the smallest number of associated hits.
127 // This procedure stops when:
128 // 1) number of associated hits is equal to the number of (remaining) hits or
129 // 2) maximal number of associated hits is less than the specified minimum.
130
131 for ( ; ; ) {
132
133 int M = (count[0] >= Nmin ? 1 : 0);
134
135 j = 0;
136
137 for (i = 1; i != n; ++i) {
138 if (count[i] < count[j]) {
139 j = i;
140 }
141 if (count[i] >= Nmin) {
142 ++M;
143 }
144 }
145
146 // Ready?
147
148 if (count[j] == n) {
149 return buffer + n;
150 }
151
152 if (M < Nmin) {
153 return buffer;
154 }
155
156 // Reduce effective size.
157
158 --n;
159
160 // Swap the selected hit to end.
161
162 swap(buffer[j], buffer[n]);
163 swap(count [j], count [n]);
164
165 // Decrease number of associated hits for each associated hit.
166
167 for (i = 0; i != n && count[n] != 1; ++i) {
168 if (match(buffer[i], buffer[n])) {
169 --count[i];
170 --count[n];
171 }
172 }
173 }
174 }
175
176 return buffer;
177 }
178
179
181
183
184
185 /**
186 * Anonymous structure for reverse clustering of hits.
187 */
188 static const struct reverse_clusterize {
189
190 /**
191 * Partition data according given binary match operator.
192 *
193 * The underlying algorithm is known in literature as reverse 'clique'.
194 * The result is (likely to be) the maximal sub-set with all elements matched to each other.
195 * The complexity is quadratic, i.e.\ at most (number of elements x number of elements) operations.
196 * The algorithm will sort the data such that all clusterized hits are at the front.
197 * The return value points the first non clusterized hit.
198 *
199 * The hit iterator refers to a data structure which should conform with the match operator.
200 *
201 * \param __begin begin of data
202 * \param __end end of data
203 * \param match binary match operator
204 * \return end of data
205 */
206 template<class JHitIterator_t, class JMatch_t>
207 inline JHitIterator_t operator()(JHitIterator_t __begin,
208 JHitIterator_t __end,
209 const JMatch_t& match) const
210 {
211 return (*this)(__begin, std::distance(__begin,__end), match, typename std::iterator_traits<JHitIterator_t>::iterator_category());
212 }
213
214 private:
215 /**
216 * Implementation of method reverse_clusterize for random access iterators.
217 *
218 * \param buffer pointer to data
219 * \param N number of hits
220 * \param match binary match operator
221 * \param tag iterator tag
222 * \return pointer to end of data
223 */
224 template<class JHitIterator_t, class JMatch_t>
225 inline JHitIterator_t operator()(JHitIterator_t buffer,
226 const int N,
227 const JMatch_t& match,
228 std::random_access_iterator_tag tag) const
229 {
230 using namespace std;
231
232 if (N != 0) {
233
234 int i, j;
235
236 // Determine number of associated hits for each hit.
237
238 count.resize(N);
239
240 for (vector<int>::iterator __i = count.begin(); __i != count.end(); ++__i) {
241 *__i = 1; // Assume always a match with itself.
242 }
243
244 for (i = 0; i != N; ++i) {
245 for (j = 0; j != i; ++j) {
246 if (match(buffer[i], buffer[j])) {
247 ++count[i];
248 ++count[j];
249 }
250 }
251 }
252
253 // Keep hit with the largest number of associated hits.
254 // This procedure stops when the number of associated hits is equal to one.
255
256 for (int n = 0; ; ++n) {
257
258 j = n;
259
260 for (i = j; ++i != N; ) {
261 if (count[i] > count[j]) {
262 j = i;
263 }
264 }
265
266 // Ready?
267
268 if (count[j] == 1) {
269 return buffer + n;
270 }
271
272 // Swap the selected hit to begin.
273
274 swap(buffer[j], buffer[n]);
275 swap(count [j], count [n]);
276
277 // Decrease number of associated hits for each associated hit.
278
279 for (i = n; ++i != N; ) {
280 if (match(buffer[i], buffer[n])) {
281 --count[i];
282 --count[n];
283 }
284 }
285 }
286 }
287
288 return buffer;
289 }
290
291
293
295
296
297 /**
298 * Anonymous struct for weighed clustering of hits.
299 */
300 static const struct clusterizeWeight {
301
302 /**
303 * Partition data according given binary match operator.
304 *
305 * The underlying algorithm is known in literature as reverse 'clique'.
306 * The result is (likely to be) the maximal sub-set with all elements matched to each other.
307 * The complexity is quadratic, i.e.\ at most (number of elements x number of elements) operations.
308 * The algorithm will sort the data such that all clusterized hits are at the front.
309 * The return value points the first non clusterized hit.
310 * Note that the weight is assumed to be positive definite and the larger the weight the better.
311 *
312 * The hit iterator refers to a data structure which should conform with the match operator.
313 * In addition, it should have the following member method:
314 * - double %getW(); // [a.u.]
315 *
316 * \param __begin begin of data
317 * \param __end end of data
318 * \param match binary match operator
319 * \return end of data
320 */
321 template<class JHitIterator_t, class JMatch_t>
322 inline JHitIterator_t operator()(JHitIterator_t __begin,
323 JHitIterator_t __end,
324 const JMatch_t& match) const
325 {
326 return (*this)(__begin, std::distance(__begin,__end), match, typename std::iterator_traits<JHitIterator_t>::iterator_category());
327 }
328
329 private:
330 /**
331 * Implementation of method clusterizeWeight for random access iterators.
332 *
333 * \param buffer pointer to data
334 * \param N number of hits
335 * \param match binary match operator
336 * \param tag iterator tag
337 * \return pointer to end of data
338 */
339 template<class JHitIterator_t, class JMatch_t>
340 inline JHitIterator_t operator()(JHitIterator_t buffer,
341 const int N,
342 const JMatch_t& match,
343 std::random_access_iterator_tag tag) const
344 {
345 using namespace std;
346
347 if (N != 0) {
348
349 int i, j;
350
351 // Determine weight of each hit.
352
353 weight.resize(N);
354
355 for (i = 0; i != N; ++i) {
356 weight[i] = buffer[i].getW(); // Assume always a match with itself.
357 }
358
359 for (i = 0; i != N; ++i) {
360 for (j = i; ++j != N; ) {
361 if (match(buffer[i], buffer[j])) {
362 weight[i] += buffer[j].getW();
363 weight[j] += buffer[i].getW();
364 }
365 }
366 }
367
368 // Remove hit with the smallest weight of associated hits.
369 // This procedure stops when the weight of associated hits
370 // is equal to the maximal weight of (remaining) hits.
371
372 int n = N;
373 double W;
374
375 for ( ; ; ) {
376
377 j = 0;
378 W = weight[j];
379
380 for (i = 1; i != n; ++i) {
381 if (weight[i] < weight[j])
382 j = i;
383 else if (weight[i] > W)
384 W = weight[i];
385 }
386
387 // Ready?
388
389 if (weight[j] == W) {
390 return buffer + n;
391 }
392
393 // Reduce effective size.
394
395 --n;
396
397 // Swap the selected hit to end.
398
399 swap(buffer[j], buffer[n]);
400 swap(weight[j], weight[n]);
401
402 // Decrease weight of associated hits for each associated hit.
403
404 for (i = 0; i != n && weight[n] > buffer[n].getW(); ++i) {
405 if (match(buffer[i], buffer[n])) {
406 weight[i] -= buffer[n].getW();
407 weight[n] -= buffer[i].getW();
408 }
409 }
410 }
411 }
412
413 return buffer;
414 }
415
416
418
420
421
422 /**
423 * Compare two hits by weight.
424 *
425 * The template argument <tt>JHit_t</tt> refers to a data structure which should have the following member method:
426 * - double %getW(); // [a.u.]
427 *
428 * \param first first hit
429 * \param second second hit
430 * \return true if first hit has larger weight than second; else false
431 */
432 template<class JHit_t>
433 inline bool weightSorter(const JHit_t& first, const JHit_t& second)
434 {
435 return first.getW() > second.getW();
436 }
437
438
439 /**
440 * Compare two hits by weight.
441 *
442 * The template argument <tt>JHit_t</tt> refers to a data structure which should have the following member methods:
443 * - double %getT(); // [a.u.]
444 *
445 * \param first first hit
446 * \param second second hit
447 * \return true if first hit earlier than second; else false
448 */
449 template<class JHit_t>
450 inline bool timeSorter(const JHit_t& first, const JHit_t& second)
451 {
452 return first.getT() < second.getT();
453 }
454}
455
456#endif
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for triggering.
static const struct JTRIGGER::reverse_clusterize reverse_clusterize
static const struct JTRIGGER::clusterize clusterize
JBinder2nd< JHit_t > JBind2nd(const JMatch< JHit_t > &match, const JHit_t &second)
Auxiliary method to create JBinder2nd object.
Definition JBind2nd.hh:66
static const struct JTRIGGER::clusterizeWeight clusterizeWeight
bool weightSorter(const JHit_t &first, const JHit_t &second)
Compare two hits by weight.
bool timeSorter(const JHit_t &first, const JHit_t &second)
Compare two hits by weight.
Definition root.py:1
Anonymous struct for weighed clustering of hits.
std::vector< double > weight
JHitIterator_t operator()(JHitIterator_t buffer, const int N, const JMatch_t &match, std::random_access_iterator_tag tag) const
Implementation of method clusterizeWeight for random access iterators.
JHitIterator_t operator()(JHitIterator_t __begin, JHitIterator_t __end, const JMatch_t &match) const
Partition data according given binary match operator.
Anonymous structure for clustering of hits.
Definition JAlgorithm.hh:23
JHitIterator_t operator()(JHitIterator_t __begin, JHitIterator_t __end, const JComparator_t &comparator, const JMatch_t &match) const
Select best root hit according given comparator and partition remaining data according given binary m...
Definition JAlgorithm.hh:65
JHitIterator_t operator()(JHitIterator_t __begin, JHitIterator_t __end, const JMatch_t &match, const int Nmin=1) const
Partition data according given binary match operator.
Definition JAlgorithm.hh:43
std::vector< int > count
JHitIterator_t operator()(JHitIterator_t buffer, const int N, const JMatch_t &match, const int Nmin, std::random_access_iterator_tag tag) const
Implementation of method clusterize for random access iterators.
Definition JAlgorithm.hh:96
Anonymous structure for reverse clustering of hits.
std::vector< int > count
JHitIterator_t operator()(JHitIterator_t buffer, const int N, const JMatch_t &match, std::random_access_iterator_tag tag) const
Implementation of method reverse_clusterize for random access iterators.
JHitIterator_t operator()(JHitIterator_t __begin, JHitIterator_t __end, const JMatch_t &match) const
Partition data according given binary match operator.