ATLAS Offline Software
Loading...
Searching...
No Matches
CombinatoricsOdometer.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
23
25
27FlexDigit::FlexDigit( int digitMax, FlexDigit* nextDigit )
28{
29 m_digit=0;
30 m_digitMax=digitMax-1;
31 m_nextDigit=nextDigit;
32}
33
34
36{
37 if(this->isAtMax())
38 {
39 this->setDigit( 0 );
40 if(!this->isFirstDigit()) (*(this->next()))++;
41 }
42 else
43 {
44 this->setDigit( this->digit()+1 );
45 }
46 return *this;
47}
48
49
51FlexDigits::FlexDigits( std::vector<std::string>& labels, std::map<std::string, int>& digitMax ) :
52 DataVector<FlexDigit>(SG::OWN_ELEMENTS)
53{
54 m_started=false;
55 this->reserve(labels.size());
56 for (const std::string& label : labels)
57 {
58 FlexDigit* temp = new FlexDigit(digitMax[label]);
59 this->push_back(temp);
60 }
61}
62
63
64FlexDigits::FlexDigits( int numDigits, int digitMax ) :
65 DataVector<FlexDigit>(SG::OWN_ELEMENTS)
66{
67 m_started=false;
68 this->reserve(numDigits);
69 for( int i=0; i<numDigits; i++ )
70 {
71 FlexDigit* temp = new FlexDigit(digitMax);
72 this->push_back(temp);
73 }
74}
75
76
80
81
82//overloaded vector method, need to tell each digit which one
83//is next to it
85{
86 if(this->size())
87 {
88 aDigit->setNext(this->back());
89 }
91}
92
93//just increment by one, no uniqueness check etc (overloaded in OdoMeter)
95{
96 if(m_started && this->isZero())
97 {
98 return false;
99 }
100 else
101 {
102 m_started = true;
103 }
104 (*this)++;
105 return true;
106}
107
108
109//for debugging
111{
112 std::cout<<"current State of digits: ";
113 for (const FlexDigit* digit : *this)
114 {
115 std::cout<<"|"<<digit->digit()<<"|";
116 }
117 std::cout<<std::endl;
118}
119
120
121//if the whole digits are 0
123{
124 bool isZero=true;
125 for (const FlexDigit* digit : *this)
126 {
127 isZero = isZero && !digit->digit();
128 }
129 return isZero;
130}
131
132
133//only ++ operaor defined (only thing needed for now)
135{
136 if( this->size() )
137 {
138 (*(this->back()))++;
139 }
140 return *this;
141}
142
143
145//somewhat specific constructor for label and number of paritlces
146//in each container with the label
147OdoMeter::OdoMeter( std::vector<std::string>& labels, std::map<std::string, int>& digitMax )
148 : FlexDigits( labels, digitMax ),
149 m_pairMeter(0)
150{
151 m_onlyUnique = true;
152 m_onlySingleEntry = true;
153 m_numLabels = labels.size();
154 int counter = 0;
155 for( ;counter < m_numLabels; counter++ )
156 {
157 m_digitAssoc[labels[counter]].insert(counter);
158 m_labels.insert(labels[counter]);
159 }
160}
161
162
163//this constructor is for the case when you want to combine
164//M objects (numDigits) from one single list of n (digitMax)
165OdoMeter::OdoMeter( int numDigits, int digitMax )
166 : FlexDigits( numDigits, digitMax ),
167 m_pairMeter(0)
168{
169 m_onlyUnique = true;
170 m_onlySingleEntry = true;
171 m_numLabels = numDigits;
172 int counter = 0;
173 for( ;counter < m_numLabels; counter++ )
174 {
175 m_digitAssoc["dummy"].insert(counter);
176 m_labels.insert("dummy");
177 }
178}
179
180
182{
183 delete m_pairMeter;
184 m_pairMeter = NULL;
185}
186
187
188
189//this function make sure that there's no double counting, should be used in combination
190//with hasOnlySingleEntry as isUnique will pass the ones with same entries from one container
191bool OdoMeter::isUnique( bool doCheck )
192{
193 if(!doCheck)
194 {
195 return true;
196 }
197 for (const std::string& label : m_labels)
198 {
199 int leftDigit = -1;
200 for (int digit : m_digitAssoc[label])
201 {
202 if(leftDigit <= (*this)[digit]->digit())
203 {
204 leftDigit=(*this)[digit]->digit();
205 }
206 else
207 {
208 return false;
209 }
210 }
211 }
212 return true;
213}
214
215
216//this function make sure that two same entries from single container do not exist
217//the method uses the notion of std::set which does not allow two same entries.
219{
220 if(!doCheck)
221 {
222 return true;
223 }
224 for (const std::string& label : m_labels)
225 {
226 std::set<int> digitsForLabel;
227 for (int digit : m_digitAssoc[label])
228 {
229 digitsForLabel.insert((*this)[digit]->digit());
230 }
231 if (digitsForLabel.size()!=m_digitAssoc[label].size())
232 {
233 return false;
234 }
235 }
236 return true;
237}
238
239
240//increment the meter by one and check uniqueness. if not unique,
241//call itself again (recursive)
243{
244 if(this->hasStarted() && this->isZero())
245 {
246 return false;
247 }
248 else if(!this->hasStarted())
249 {
250 this->setStarted() ;
251 }
252 (*this)++;
253 bool found = true;
255 {
256 found=false;
257 }
259 {
260 found=false;
261 }
262 if(!found)
263 {
264 return this->increment();
265 }
266 else
267 {
268 delete m_pairMeter;
270 return true;
271 }
272}
273
274
275//output the digit in the form of vector<int>
276std::vector<int> OdoMeter::getVector()
277{
278 std::vector<int> digitsVector;
279 for (const FlexDigit* digit : *this)
280 {
281 digitsVector.push_back(digit->digit());
282 }
283 return digitsVector;
284}
285
286
287//increment() for pairMeter
289{
290 if(m_pairMeter)
291 {
292 if( m_pairMeter->increment())
293 {
294 return true;
295 }
296 else
297 {
298 delete m_pairMeter;
299 m_pairMeter = NULL;
300 }
301 }
302 return false;
303}
304
305
306//get unique pairs out of the combined particles (useful for overlap check
307std::pair<int,int> OdoMeter::getPair()
308{
309 if(m_pairMeter)
310 {
311 return std::make_pair( (*m_pairMeter)[0]->digit(), (*m_pairMeter)[1]->digit() );
312 }
313 else
314 {
315 return std::make_pair( 0,0 );
316 }
317}
318
319
321PairMeter::PairMeter( int digitMax )
322 :OdoMeter( 2, digitMax )
323{
324}
325
326
330
331
333{
334 if(this->hasStarted() && this->isZero())
335 {
336 return false;
337 }
338 else if(!this->hasStarted())
339 {
340 this->setStarted() ;
341 }
342 (*this)++;
343 bool found = true;
344 if(!isUnique(true))
345 {
346 found=false;
347 }
348 if(!hasOnlySingleEntry(true))
349 {
350 found=false;
351 }
352 if(!found)
353 {
354 return this->increment();
355 }
356 else
357 {
358 return true;
359 }
360}
const FlexDigit * back() const
void reserve(size_type n)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataVector(SG::OwnershipPolicy ownPolicy=SG::OWN_ELEMENTS, SG::IndexTrackingPolicy trackIndices=SG::DEFAULT_TRACK_INDICES)
size_type size() const noexcept
FlexDigit(int, FlexDigit *=0)
void setDigit(int digit)
FlexDigit * m_nextDigit
FlexDigit operator++(int)
void setNext(FlexDigit *next)
int digit() const
FlexDigit * next()
virtual bool increment()
virtual void print()
FlexDigits(std::vector< std::string > &labels, std::map< std::string, int > &digitMax)
virtual void push_back(FlexDigit *)
virtual FlexDigits & operator++(int)
bool isUnique(bool doCheck)
OdoMeter * m_pairMeter
std::vector< int > getVector()
std::pair< int, int > getPair()
std::set< std::string > m_labels
std::map< std::string, std::set< int > > m_digitAssoc
bool hasOnlySingleEntry(bool doCheck)
virtual bool increment()
OdoMeter(std::vector< std::string > &labels, std::map< std::string, int > &numObj)
PairMeter(int numDigits)
virtual bool increment()
std::string label(const std::string &format, int i)
Definition label.h:19
Forward declaration.