CMS 3D CMS Logo

MixCollection.h
Go to the documentation of this file.
1 #ifndef MIX_COLLECTION_H
2 #define MIX_COLLECTION_H
3 #include <utility>
4 #include <string>
5 #include <vector>
6 
9 
10 template <class T>
12 
13  private:
14 
15  public:
16  typedef std::pair<int,int> range;
17  MixCollection();
19  const range bunchRange =range(-999,999));
20  MixCollection(const std::vector<const CrossingFrame<T> *>& cfs,
21  const range bunchRange =range(-999,999));
22 
23  range bunchrange() const {return bunchRange_;}
24  int size() const {return sizeSignal() + sizePileup();}
25  int sizePileup() const;
26  int sizeSignal() const;
27  // false if at least one of the subdetectors was not found in registry
28  bool inRegistry() const {return inRegistry_;}
29 
30  // get object the index of which -in the whole collection- is known
31  const T & getObject(unsigned int ip) const {
32  if (ip>=(unsigned int)size()) throw cms::Exception("BadIndex")<<"MixCollection::getObject called with an invalid index!"; // ip >= 0, since ip is unsigned
33  int n=ip;
34 /*
35 - int iframe=0;
36 - for (unsigned int ii=0;ii<crossingFrames_.size();++ii) {
37 - iframe=ii;
38 - int s=crossingFrames_[iframe]->getNrSignals()+crossingFrames_[iframe]->getNrPileups();
39 - if (n<s) break;
40 */
41  for (unsigned int iframe=0;iframe<crossingFrames_.size();++iframe) {
42  int s=crossingFrames_[iframe]->getNrSignals();
43  if (n<s) return crossingFrames_[iframe]->getObject(n);
44  n=n-s;
45  }
46 /*
47  return crossingFrames_[iframe]->getObject(n);
48 */
49  for (unsigned int iframe=0;iframe<crossingFrames_.size();++iframe) {
50  int s=crossingFrames_[iframe]->getNrSignals();
51  int p=crossingFrames_[iframe]->getNrPileups();
52  if (n<p) return crossingFrames_[iframe]->getObject(s+n);
53  n=n-p;
54  }
55  throw cms::Exception("InternalError")<<"MixCollection::getObject reached impossible condition";
56  }
57 
58  class MixItr;
59  friend class MixItr;
60 
61  // nested class for iterator
62  class MixItr {
63  public:
64  struct end_tag {};
65 
68  MixItr(const MixCollection *shc, int nrDets, end_tag): internalCtr2_(0) {
69  for(int i=0; i<nrDets; ++i) {
70  const auto& cf = shc->crossingFrames_[i];
71  internalCtr2_ += cf->getSignal().size() + cf->getPileups().size();
72  }
73  }
74  MixItr(const MixCollection *shc, int nrDets) :
75  mixCol_(shc),nrDets_(nrDets),first_(true),iSignal_(0),iPileup_(0),internalCtr_(0) {;}
76 
77 
79  virtual ~MixItr() {;}
80 
82  // default version valid for HepMCProduct
83  const T* operator->() const { return *(pMixItr_.operator->()); }
84  const T& operator*() const {return *(pMixItr_.operator*()); }
85  const MixItr operator++ () {return next();}
86  const MixItr operator++ (int) {return next();}
87  bool operator!= (const MixItr& itr) { return internalCtr2_ != itr.internalCtr2_; }
88 
90  int bunch() const {
91  if (trigger_) return 0;
92  int bcr= myCF_->getBunchCrossing(internalCtr_);
93  return bcr;
94  }
95 
96  bool getTrigger() const {return trigger_;}
97 
98  int getSourceType() const {return (getTrigger() ? -1 : myCF_->getSourceType(internalCtr_));}
99  int getPileupEventNr() const {return (getTrigger() ? 0 : myCF_->getPileupEventNr(internalCtr_));}
100 
101  private:
102 
103  typename std::vector<const T *>::const_iterator pMixItr_;
104  typename std::vector<const T *>::const_iterator pMixItrEnd_;
105 
108  int nrDets_;
109  bool first_;
111  bool trigger_;
112  unsigned int internalCtr_; //this is the internal counter pointing into the vector of piled up objects
113  unsigned int internalCtr2_ = 0; // this is the internal counter for the number of iterated elements, needed for operator!=
114 
115  const MixItr next();
116  void reset() {;}
117  bool getNewSignal(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last);
118 
119  bool getNewPileups(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) ;
120  };
121 
122  typedef MixItr iterator;
123  iterator begin() const;
124  iterator end() const;
125 
126  private:
127  void init( const range bunchRange);
128 
129  range bunchRange_;
131  int nrDets_;
132 
133  std::vector<const CrossingFrame<T> *> crossingFrames_;
134 
135 };
136 
138 //
139 // Exceptions
140 //
142 template <class T>
145 {
146  crossingFrames_.push_back(NULL);
147 }
148 
149 template <class T>
150 MixCollection<T>::MixCollection(const CrossingFrame<T> *cf,const std::pair<int,int> bunchRange) :
151  inRegistry_(false),nrDets_(0)
152 {
153  nrDets_=1;
154  inRegistry_=true;
155  if (cf) {
156  crossingFrames_.push_back(cf);
157  init(bunchRange);
158  }
159  else edm::LogWarning("MixCollectionInvalidCtr") <<"Could not construct MixCollection for "<<typeid(T).name() <<", pointer to CrossingFrame invalid!"<<std::endl;
160 }
161 
162 template <class T>
163 MixCollection<T>::MixCollection(const std::vector<const CrossingFrame<T> *>& cfs, const std::pair<int,int> bunchRange) : inRegistry_(false) , nrDets_(0)
164 {
165  // first, verify that all CrossingFrames have the same bunchrange
166  range bR=cfs[0]->getBunchRange();
167  for (unsigned int i=1;i<cfs.size();++i) {
168  if (bR!= cfs[i]->getBunchRange()) throw cms::Exception("Incompatible CrossingFrames")<<"You gave as input CrossingFrames with different bunchRanges!";
169  }
170 
171  //set necessary variables
172  for (unsigned int i=0;i<cfs.size();++i) {
173  nrDets_++;
174  crossingFrames_.push_back(cfs[i]);
175  inRegistry_=true; // true if at least one is present
176  }
177 
178  init(bunchRange);
179 }
180 
181 template <class T>
182 void MixCollection<T>::init( const std::pair<int,int> bunchRange) {
183 
184  bunchRange_=bunchRange;
185 
186  //verify whether bunchrange is ok
187  // in case of several crossingFrames, we have verified before that they have the same bunchrange
188  range defaultrange=crossingFrames_[0]->getBunchRange();
189  if (bunchRange_==range(-999,999)) bunchRange_=defaultrange;
190  else if (bunchRange_!=defaultrange ) {
191  int first=defaultrange.first;
192  int last = defaultrange.second;
193  if (bunchRange_.first<defaultrange.first || bunchRange_.second>defaultrange.second ) throw cms::Exception("BadRunRange")<<" You are asking for a runrange ("<<bunchRange_.first<<","<<bunchRange_.second<<"), outside of the existing runrange ("<<defaultrange.first<<", "<<defaultrange.second<<")\n";
194  bunchRange_=range(first,last);
195  }
196 }
197 
198 template <class T> int MixCollection<T>::sizePileup() const {
199  // get size cumulated for all subdetectors
200  int s=0;
201  for (int i=0;i<nrDets_;++i) {
202  s+=crossingFrames_[i]->getNrPileups();
203  } return s;
204 }
205 
206 template <class T> int MixCollection<T>::sizeSignal() const {
207  int s=0;
208  for (int i=0;i<nrDets_;++i) {
209  s+=crossingFrames_[i]->getNrSignals();
210  }
211  return s;
212 }
213 
214 template <class T>
215 bool MixCollection<T>::MixItr::getNewSignal(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) {
216  // gets the next signal collection with non-zero size
217 
218  while (iSignal_<nrDets_) {
219  mixCol_->crossingFrames_[iSignal_]->getSignal(first,last);
220  myCF_=mixCol_->crossingFrames_[iSignal_];
221  iSignal_++;
222  if (first != last) return true;
223  }
224  return false;
225 }
226 
227 template <class T>
228 bool MixCollection<T>::MixItr::getNewPileups(typename std::vector<const T*>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) {
229 
230  // gets the next pileup collection , changing subdet if necessary
231  while (iPileup_<nrDets_) {
232  mixCol_-> crossingFrames_[iPileup_]->getPileups(first,last);
233  int s=0;
234  for (typename std::vector<const T*>::const_iterator it=first;it!= last ;it++) {
235  s++;
236  }
237  myCF_=mixCol_->crossingFrames_[iPileup_];
238  iPileup_++;
239  if (first!=last) return true;
240  }
241  return false;
242 }
243 
244 template <class T>
246 
247  // initialisation
248  if (first_) {
249  first_=false;
250  trigger_=true;
251  } else {
252  ++internalCtr2_;
253  if (!trigger_) internalCtr_++;
254  if (++pMixItr_!=pMixItrEnd_) return *this;
255  }
256 
257  // we have an end condition, look whether there are more collections
258  bool ok;
259  if (trigger_) {
260  ok=this->getNewSignal(pMixItr_,pMixItrEnd_);
261  if (ok) return *this;
262  trigger_=false;
263  }
264  ok=this->getNewPileups(pMixItr_,pMixItrEnd_);
265  if (ok) {
266  // debug print start
267  // for (auto dbIt=pMixItr_;dbIt!=pMixItrEnd_;++dbIt) printf("Found pointer %p\n",(*dbIt));fflush(stdout);
268  // debug print end
269  internalCtr_=0;
270  }
271  return *this; // with internalCtr2_ we can always return *this
272 }
273 
274 template <class T>
276  return MixItr(this,nrDets_)++;
277 }
278 
279 template <class T>
281  return MixItr(this,nrDets_,typename MixItr::end_tag());
282 }
283 
284 #include<iosfwd>
285 #include<iostream>
286 template <class T>
287 std::ostream &operator<<(std::ostream& o, const MixCollection<T>& col)
288 {
289  o << "MixCollection with bunchRange: "<<(col.bunchrange()).first<< "," << (col.bunchrange()).second <<" size of signal: "<<col.sizeSignal() <<" ,size of pileup: "<<col.sizePileup();
290 
291 
292  return o;
293 }
294 
295 #endif
296 
const CrossingFrame< T > * myCF_
const T * operator->() const
Definition: MixCollection.h:83
const MixCollection * mixCol_
bool inRegistry() const
Definition: MixCollection.h:28
#define NULL
Definition: scimark2.h:8
MixItr(const MixCollection *shc, int nrDets, end_tag)
Definition: MixCollection.h:68
const T & operator*() const
Definition: MixCollection.h:84
int size() const
Definition: MixCollection.h:24
bool getTrigger() const
Definition: MixCollection.h:96
MixItr(const MixCollection *shc, int nrDets)
Definition: MixCollection.h:74
U second(std::pair< T, U > const &p)
std::vector< const CrossingFrame< T > * > crossingFrames_
bool operator!=(const MixItr &itr)
Definition: MixCollection.h:87
int sizeSignal() const
const std::vector< const T * > & getPileups() const
Definition: CrossingFrame.h:96
bool getNewSignal(typename std::vector< const T * >::const_iterator &first, typename std::vector< const T * >::const_iterator &last)
const std::vector< const T * > & getSignal() const
Definition: CrossingFrame.h:97
unsigned int internalCtr2_
iterator end() const
bool getNewPileups(typename std::vector< const T * >::const_iterator &first, typename std::vector< const T * >::const_iterator &last)
std::vector< const T * >::const_iterator pMixItr_
const T & getObject(unsigned int ip) const
Definition: MixCollection.h:31
std::vector< const T * >::const_iterator pMixItrEnd_
col
Definition: cuy.py:1010
int getPileupEventNr() const
Definition: MixCollection.h:99
int getSourceType() const
Definition: MixCollection.h:98
int sizePileup() const
iterator begin() const
long double T
void init(const range bunchRange)
std::pair< int, int > range
Definition: MixCollection.h:16
unsigned int internalCtr_
const MixItr operator++()
Definition: MixCollection.h:85
range bunchrange() const
Definition: MixCollection.h:23
friend class MixItr
Definition: MixCollection.h:58
const MixItr next()