ATLAS Offline Software
Loading...
Searching...
No Matches
AnalysisCombination.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef ANALYSISUTILS_ANALYSISCOMBINATION_H
6#define ANALYSISUTILS_ANALYSISCOMBINATION_H
7
13
14#include <vector>
15
16namespace AnalysisUtils {
17
20 template <class COLL> class Combination {
21
22 public:
23
28 Combination(COLL *coll, const unsigned int nElement);
29
33
36 void reset();
37
42 template <class OUT>
43 bool get(OUT &comb)
44 {
45 // init returned combination
46 comb.clear();
47
48 if (m_first) {
49 if (m_index[m_nElement-1] >= m_coll->size()) return false;
50 m_first = false;
51 } else {
52 // increment indices
53 if (!setNewIndex(m_nElement-1)) return false;
54 }
55
56 // assign to returned combination
57 for (unsigned int i=0; i<m_nElement; ++i)
58 comb.push_back((*m_coll)[m_index[i]]);
59
60 return true;
61 }
62
69 template <class CALLER, class OUT, class CRITERIA>
70 bool goodOnes(CALLER *caller, OUT &comb, CRITERIA criteria)
71 {
72 bool ret = get(comb);
73 if (!ret) return false;
74
75 // check if this passes the criteria
76 if (criteria(caller, comb)) return true;
77
78 // if not, look for next combination
79 return goodOnes(caller, comb, criteria);
80 }
81
84 template <class OUT>
85 bool get(OUT &comb, OUT &remain)
86 {
87 // init returned vector
88 remain.clear();
89
90 bool ret = get(comb);
91 if (!ret) return false;
92
93 // assigin to remain
94 unsigned int sIndex = 0;
95 std::vector<unsigned int>::const_iterator it = m_index.begin();
96 std::vector<unsigned int>::const_iterator itE = m_index.end();
97 for (; ; ++it)
98 {
99 unsigned int eIndex;
100 if (it!=itE)
101 eIndex = *it;
102 else
103 eIndex = m_coll->size();
104
105 for (unsigned int i=sIndex; i<eIndex; ++i)
106 remain.push_back((*m_coll)[i]);
107 sIndex = eIndex+1;
108
109 if (it == itE) break;
110 }
111
112 return true;
113 }
114
118 template <class CALLER, class OUT, class CRITERIA>
119 bool goodOnes(CALLER *caller, OUT &comb, OUT &remain, CRITERIA criteria)
120 {
121 bool ret = get(comb, remain);
122 if (!ret) return false;
123
124 // check if this passes the criteria
125 if (criteria(caller, comb)) return true;
126
127 // if not, look for next combination
128 return goodOnes(caller, comb, remain, criteria);
129 }
130
131 private:
132
134 COLL *m_coll;
135
137 const unsigned int m_nElement;
138
140 std::vector<unsigned int> m_index;
141
144
146 bool setNewIndex (int iElement);
147 };
148
149
151 // implementation
152
153 template <class COLL> inline Combination<COLL>::Combination(COLL *coll, const unsigned int nElement)
154 : m_coll(coll), m_nElement(nElement), m_first(true)
155 {
156 // init indices
157 // internal indices are [0,1,2...] at beginning
158 for (unsigned int i=0; i<nElement; ++i)
159 m_index.push_back(i);
160 }
161
162 template <class COLL> inline void Combination<COLL>::reset()
163 {
164 // reset indices
165 m_index.clear();
166 for (unsigned int i=0; i<m_nElement; ++i)
167 m_index.push_back(i);
168
169 // set first flag
170 m_first = true;
171 }
172
173 // iElement runs over 0..(m_nElement-1)
174 template <class COLL> inline bool Combination<COLL>::setNewIndex (int iElement)
175 {
176 if (iElement < 0) return false;
177
178 if (iElement+1 == static_cast<int>(m_nElement))
179 {
180 if ((m_index[iElement]+1) < m_coll->size())
181 {
182 ++(m_index[iElement]);
183 return true;
184 }
185 }
186 else
187 {
188 if ((m_index[iElement]+1) < m_index[iElement+1])
189 {
190 ++(m_index[iElement]);
191 return true;
192 }
193 }
194
195 if (setNewIndex (iElement-1))
196 {
197 m_index[iElement] = m_index[iElement-1]+1;
198 return true;
199 }
200
201 return false;
202 }
203
204} // end of AnalysisUtils
205
206#endif // END OF ANALYSISTOOLS_ANALYSISCOMBINATION_H
#define OUT(dst, src)
Definition MD5.cxx:316
bool get(OUT &comb, OUT &remain)
get a combination and the remaining elements
Combination(COLL *coll, const unsigned int nElement)
constructor
void reset()
reset internal indices
std::vector< unsigned int > m_index
indices of elements
bool setNewIndex(int iElement)
set new index recursively
bool goodOnes(CALLER *caller, OUT &comb, OUT &remain, CRITERIA criteria)
get a combination and the remaining elements.
bool m_first
flag to check if first
const unsigned int m_nElement
number of elements to be selected
bool get(OUT &comb)
get a combination.
bool goodOnes(CALLER *caller, OUT &comb, CRITERIA criteria)
get a combination which passes a selection criteria
utility class to select combination of elements in a collection