ATLAS Offline Software
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 
14 #include <vector>
15 
16 namespace 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 
143  bool m_first;
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
AnalysisUtils::Combination::get
bool get(OUT &comb)
get a combination.
Definition: AnalysisCombination.h:43
AnalysisUtils::Combination::m_nElement
const unsigned int m_nElement
number of elements to be selected
Definition: AnalysisCombination.h:137
AnalysisUtils::Combination
combination
Definition: AnalysisCombination.h:20
AnalysisUtils::Combination::m_index
std::vector< unsigned int > m_index
indices of elements
Definition: AnalysisCombination.h:140
AnalysisUtils::Combination::m_first
bool m_first
flag to check if first
Definition: AnalysisCombination.h:143
skel.it
it
Definition: skel.GENtoEVGEN.py:396
AnalysisUtils
utility class to select combination of elements in a collection
Definition: AnalysisCombination.h:16
AnalysisUtils::Combination::m_coll
COLL * m_coll
collection
Definition: AnalysisCombination.h:134
TruthTest.itE
itE
Definition: TruthTest.py:25
AnalysisUtils::Combination::get
bool get(OUT &comb, OUT &remain)
get a combination and the remaining elements
Definition: AnalysisCombination.h:85
AnalysisUtils::Combination::goodOnes
bool goodOnes(CALLER *caller, OUT &comb, CRITERIA criteria)
get a combination which passes a selection criteria
Definition: AnalysisCombination.h:70
OUT
#define OUT(dst, src)
Definition: MD5.cxx:316
lumiFormat.i
int i
Definition: lumiFormat.py:85
AnalysisUtils::Combination::setNewIndex
bool setNewIndex(int iElement)
set new index recursively
Definition: AnalysisCombination.h:174
AnalysisUtils::Combination::Combination
Combination(COLL *coll, const unsigned int nElement)
constructor
Definition: AnalysisCombination.h:153
AnalysisUtils::Combination::goodOnes
bool goodOnes(CALLER *caller, OUT &comb, OUT &remain, CRITERIA criteria)
get a combination and the remaining elements.
Definition: AnalysisCombination.h:119
AnalysisUtils::Combination::~Combination
~Combination()
destructor
Definition: AnalysisCombination.h:32
AnalysisUtils::Combination::reset
void reset()
reset internal indices
Definition: AnalysisCombination.h:162