Jpp - the software that should make you happy
 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 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 
182  } clusterize;
183 
184 
185  /**
186  * Anonymous structure for reverse clustering of hits.
187  */
188  static const struct {
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 
292  mutable std::vector<int> count;
293 
295 
296 
297  /**
298  * Anonymous struct for weighed clustering of hits.
299  */
300  static const struct {
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
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:450
bool weightSorter(const JHit_t &first, const JHit_t &second)
Compare two hits by weight.
Definition: JAlgorithm.hh:433
std::vector< int > count
Definition: JAlgorithm.hh:180
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:35
Nmin
std::vector< double > weight
Definition: JAlgorithm.hh:417