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