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