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