Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:41

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   // false if at least one of the subdetectors was not found in registry
0023   bool inRegistry() const { return inRegistry_; }
0024 
0025   // get object the index of which -in the whole collection- is known
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!";  // ip >= 0, since ip is unsigned
0030     int n = ip;
0031     /*
0032 -    int iframe=0;
0033 -    for (unsigned int ii=0;ii<crossingFrames_.size();++ii) {
0034 -      iframe=ii;
0035 -      int s=crossingFrames_[iframe]->getNrSignals()+crossingFrames_[iframe]->getNrPileups();
0036 -      if (n<s) break;
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     return crossingFrames_[iframe]->getObject(n);
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   // nested class for iterator
0061   class MixItr {
0062   public:
0063     struct end_tag {};
0064 
0065     /** constructors */
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     /**Default destructor*/
0079     virtual ~MixItr() { ; }
0080 
0081     /**operators*/
0082     // default version valid for HepMCProduct
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     /**getters*/
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_;  //this is the internal counter pointing into the vector of piled up objects
0113     unsigned int internalCtr2_ =
0114         0;  // this is the internal counter for the number of iterated elements, needed for operator!=
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 // Exceptions
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   // first, verify that all CrossingFrames have the same bunchrange
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   //set necessary variables
0174   for (unsigned int i = 0; i < cfs.size(); ++i) {
0175     nrDets_++;
0176     crossingFrames_.push_back(cfs[i]);
0177     inRegistry_ = true;  // true if at least one is present
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   //verify whether bunchrange is ok
0188   // in case of several crossingFrames, we have verified before that they have the same bunchrange
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   // get size cumulated for all subdetectors
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   // gets the next signal collection with non-zero size
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   // gets the next pileup collection , changing subdet if necessary
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   // initialisation
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   // we have an end condition, look whether there are more collections
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     // debug print start
0276     //    for (auto dbIt=pMixItr_;dbIt!=pMixItrEnd_;++dbIt)  printf("Found pointer %p\n",(*dbIt));fflush(stdout);
0277     // debug print end
0278     internalCtr_ = 0;
0279   }
0280   return *this;  // with internalCtr2_ we can always 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