File indexing completed on 2023-05-04 02:46:23
0001 #ifndef MIX_COLLECTION_H
0002 #define MIX_COLLECTION_H
0003 #include <utility>
0004 #include <string>
0005 #include <vector>
0006
0007 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
0008
0009 template <class T>
0010 class MixCollection {
0011 private:
0012 public:
0013 typedef std::pair<int, int> range;
0014 MixCollection();
0015 MixCollection(const CrossingFrame<T> *cf, const range bunchRange = range(-999, 999));
0016 MixCollection(const std::vector<const CrossingFrame<T> *> &cfs, const range bunchRange = range(-999, 999));
0017
0018 range bunchrange() const { return bunchRange_; }
0019 int size() const { return sizeSignal() + sizePileup(); }
0020 int sizePileup() const;
0021 int sizeSignal() const;
0022
0023 bool inRegistry() const { return inRegistry_; }
0024
0025
0026 const T &getObject(unsigned int ip) const {
0027 if (ip >= (unsigned int)size())
0028 throw cms::Exception("BadIndex")
0029 << "MixCollection::getObject called with an invalid index!";
0030 int n = ip;
0031
0032
0033
0034
0035
0036
0037
0038 for (unsigned int iframe = 0; iframe < crossingFrames_.size(); ++iframe) {
0039 int s = crossingFrames_[iframe]->getNrSignals();
0040 if (n < s)
0041 return crossingFrames_[iframe]->getObject(n);
0042 n = n - s;
0043 }
0044
0045
0046
0047 for (unsigned int iframe = 0; iframe < crossingFrames_.size(); ++iframe) {
0048 int s = crossingFrames_[iframe]->getNrSignals();
0049 int p = crossingFrames_[iframe]->getNrPileups();
0050 if (n < p)
0051 return crossingFrames_[iframe]->getObject(s + n);
0052 n = n - p;
0053 }
0054 throw cms::Exception("InternalError") << "MixCollection::getObject reached impossible condition";
0055 }
0056
0057 class MixItr;
0058 friend class MixItr;
0059
0060
0061 class MixItr {
0062 public:
0063 struct end_tag {};
0064
0065
0066 MixItr() : first_(true), internalCtr_(0) { ; }
0067 MixItr(const MixCollection *shc, int nrDets, end_tag) : internalCtr2_(0) {
0068 for (int i = 0; i < nrDets; ++i) {
0069 const auto &cf = shc->crossingFrames_[i];
0070 internalCtr2_ += cf->getSignal().size() + cf->getPileups().size();
0071 }
0072 }
0073 MixItr(const MixCollection *shc, int nrDets)
0074 : mixCol_(shc), nrDets_(nrDets), first_(true), iSignal_(0), iPileup_(0), internalCtr_(0) {
0075 ;
0076 }
0077
0078
0079 virtual ~MixItr() { ; }
0080
0081
0082
0083 const T *operator->() const { return *(pMixItr_.operator->()); }
0084 const T &operator*() const { return *(pMixItr_.operator*()); }
0085 const MixItr operator++() { return next(); }
0086 const MixItr operator++(int) { return next(); }
0087 bool operator!=(const MixItr &itr) { return internalCtr2_ != itr.internalCtr2_; }
0088
0089
0090 int bunch() const {
0091 if (trigger_)
0092 return 0;
0093 int bcr = myCF_->getBunchCrossing(internalCtr_);
0094 return bcr;
0095 }
0096
0097 bool getTrigger() const { return trigger_; }
0098
0099 int getSourceType() const { return (getTrigger() ? -1 : myCF_->getSourceType(internalCtr_)); }
0100 int getPileupEventNr() const { return (getTrigger() ? 0 : myCF_->getPileupEventNr(internalCtr_)); }
0101
0102 private:
0103 typename std::vector<const T *>::const_iterator pMixItr_;
0104 typename std::vector<const T *>::const_iterator pMixItrEnd_;
0105
0106 const CrossingFrame<T> *myCF_;
0107 const MixCollection *mixCol_;
0108 int nrDets_;
0109 bool first_;
0110 int iSignal_, iPileup_;
0111 bool trigger_;
0112 unsigned int internalCtr_;
0113 unsigned int internalCtr2_ =
0114 0;
0115
0116 const MixItr next();
0117 void reset() { ; }
0118 bool getNewSignal(typename std::vector<const T *>::const_iterator &first,
0119 typename std::vector<const T *>::const_iterator &last);
0120
0121 bool getNewPileups(typename std::vector<const T *>::const_iterator &first,
0122 typename std::vector<const T *>::const_iterator &last);
0123 };
0124
0125 typedef MixItr iterator;
0126 iterator begin() const;
0127 iterator end() const;
0128
0129 private:
0130 void init(const range bunchRange);
0131
0132 range bunchRange_;
0133 bool inRegistry_;
0134 int nrDets_;
0135
0136 std::vector<const CrossingFrame<T> *> crossingFrames_;
0137 };
0138
0139 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
0140
0141
0142
0143 #include "FWCore/Utilities/interface/Exception.h"
0144 template <class T>
0145 MixCollection<T>::MixCollection() : bunchRange_(0, 0), inRegistry_(false), nrDets_(0) {
0146 crossingFrames_.push_back(NULL);
0147 }
0148
0149 template <class T>
0150 MixCollection<T>::MixCollection(const CrossingFrame<T> *cf, const std::pair<int, int> bunchRange)
0151 : inRegistry_(false), nrDets_(0) {
0152 nrDets_ = 1;
0153 inRegistry_ = true;
0154 if (cf) {
0155 crossingFrames_.push_back(cf);
0156 init(bunchRange);
0157 } else
0158 throw cms::Exception("InvalidPtr") << "Could not construct MixCollection for " << typeid(T).name()
0159 << ", pointer to CrossingFrame invalid!";
0160 }
0161
0162 template <class T>
0163 MixCollection<T>::MixCollection(const std::vector<const CrossingFrame<T> *> &cfs, const std::pair<int, int> bunchRange)
0164 : inRegistry_(false), nrDets_(0) {
0165
0166 range bR = cfs[0]->getBunchRange();
0167 for (unsigned int i = 1; i < cfs.size(); ++i) {
0168 if (bR != cfs[i]->getBunchRange())
0169 throw cms::Exception("Incompatible CrossingFrames")
0170 << "You gave as input CrossingFrames with different bunchRanges!";
0171 }
0172
0173
0174 for (unsigned int i = 0; i < cfs.size(); ++i) {
0175 nrDets_++;
0176 crossingFrames_.push_back(cfs[i]);
0177 inRegistry_ = true;
0178 }
0179
0180 init(bunchRange);
0181 }
0182
0183 template <class T>
0184 void MixCollection<T>::init(const std::pair<int, int> bunchRange) {
0185 bunchRange_ = bunchRange;
0186
0187
0188
0189 range defaultrange = crossingFrames_[0]->getBunchRange();
0190 if (bunchRange_ == range(-999, 999))
0191 bunchRange_ = defaultrange;
0192 else if (bunchRange_ != defaultrange) {
0193 int first = defaultrange.first;
0194 int last = defaultrange.second;
0195 if (bunchRange_.first < defaultrange.first || bunchRange_.second > defaultrange.second)
0196 throw cms::Exception("BadRunRange")
0197 << " You are asking for a runrange (" << bunchRange_.first << "," << bunchRange_.second
0198 << "), outside of the existing runrange (" << defaultrange.first << ", " << defaultrange.second << ")\n";
0199 bunchRange_ = range(first, last);
0200 }
0201 }
0202
0203 template <class T>
0204 int MixCollection<T>::sizePileup() const {
0205
0206 int s = 0;
0207 for (int i = 0; i < nrDets_; ++i) {
0208 s += crossingFrames_[i]->getNrPileups();
0209 }
0210 return s;
0211 }
0212
0213 template <class T>
0214 int MixCollection<T>::sizeSignal() const {
0215 int s = 0;
0216 for (int i = 0; i < nrDets_; ++i) {
0217 s += crossingFrames_[i]->getNrSignals();
0218 }
0219 return s;
0220 }
0221
0222 template <class T>
0223 bool MixCollection<T>::MixItr::getNewSignal(typename std::vector<const T *>::const_iterator &first,
0224 typename std::vector<const T *>::const_iterator &last) {
0225
0226
0227 while (iSignal_ < nrDets_) {
0228 mixCol_->crossingFrames_[iSignal_]->getSignal(first, last);
0229 myCF_ = mixCol_->crossingFrames_[iSignal_];
0230 iSignal_++;
0231 if (first != last)
0232 return true;
0233 }
0234 return false;
0235 }
0236
0237 template <class T>
0238 bool MixCollection<T>::MixItr::getNewPileups(typename std::vector<const T *>::const_iterator &first,
0239 typename std::vector<const T *>::const_iterator &last) {
0240
0241 while (iPileup_ < nrDets_) {
0242 mixCol_->crossingFrames_[iPileup_]->getPileups(first, last);
0243 myCF_ = mixCol_->crossingFrames_[iPileup_];
0244 iPileup_++;
0245 if (first != last)
0246 return true;
0247 }
0248 return false;
0249 }
0250
0251 template <class T>
0252 const typename MixCollection<T>::MixItr MixCollection<T>::MixItr::next() {
0253
0254 if (first_) {
0255 first_ = false;
0256 trigger_ = true;
0257 } else {
0258 ++internalCtr2_;
0259 if (!trigger_)
0260 internalCtr_++;
0261 if (++pMixItr_ != pMixItrEnd_)
0262 return *this;
0263 }
0264
0265
0266 bool ok;
0267 if (trigger_) {
0268 ok = this->getNewSignal(pMixItr_, pMixItrEnd_);
0269 if (ok)
0270 return *this;
0271 trigger_ = false;
0272 }
0273 ok = this->getNewPileups(pMixItr_, pMixItrEnd_);
0274 if (ok) {
0275
0276
0277
0278 internalCtr_ = 0;
0279 }
0280 return *this;
0281 }
0282
0283 template <class T>
0284 typename MixCollection<T>::MixItr MixCollection<T>::begin() const {
0285 return MixItr(this, nrDets_)++;
0286 }
0287
0288 template <class T>
0289 typename MixCollection<T>::MixItr MixCollection<T>::end() const {
0290 return MixItr(this, nrDets_, typename MixItr::end_tag());
0291 }
0292
0293 #include <iosfwd>
0294 #include <iostream>
0295 template <class T>
0296 std::ostream &operator<<(std::ostream &o, const MixCollection<T> &col) {
0297 o << "MixCollection with bunchRange: " << (col.bunchrange()).first << "," << (col.bunchrange()).second
0298 << " size of signal: " << col.sizeSignal() << " ,size of pileup: " << col.sizePileup();
0299
0300 return o;
0301 }
0302
0303 #endif