CMS 3D CMS Logo

MixCollection.h

Go to the documentation of this file.
00001 #ifndef MIX_COLLECTION_H
00002 #define MIX_COLLECTION_H
00003 #include <utility>
00004 #include <string>
00005 #include <vector>
00006 
00007 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00008 
00009 template <class T> 
00010 class MixCollection {
00011 
00012  private:
00013 
00014  public:
00015   typedef std::pair<int,int> range;
00016   MixCollection();
00017   MixCollection(const CrossingFrame<T> *cf, 
00018                 const range bunchRange =range(-999,999));
00019   MixCollection(std::vector<const CrossingFrame<T> *> cfs, 
00020                 const range bunchRange =range(-999,999));
00021 
00022   range bunchrange() const {return bunchRange_;}
00023   int size() const {return sizeSignal() + sizePileup();}
00024   int sizePileup() const;
00025   int sizeSignal() const;
00026   // false if at least one of the subdetectors was not found in registry
00027   bool inRegistry() const {return inRegistry_;}
00028 
00029   // get object the index of which -in the whole collection- is known
00030   const T & getObject(unsigned int ip) const { 
00031     if (ip<0 || ip>=(unsigned int)size()) throw cms::Exception("BadIndex")<<"MixCollection::getObject called with an invalid index!";
00032     int n=ip;
00033     int iframe=0;
00034     for (unsigned int ii=0;ii<crossingFrames_.size();++ii) {
00035       iframe=ii;
00036       int s=crossingFrames_[iframe]->getNrSignals()+crossingFrames_[iframe]->getNrPileups();
00037       if (n<s) break;
00038       n=n-s;
00039     }
00040     return crossingFrames_[iframe]->getObject(n);
00041   }
00042 
00043   class MixItr;
00044   friend class MixItr;
00045 
00046   // nested class for iterator
00047   class MixItr {
00048   public:
00049 
00051     MixItr():first_(true), internalCtr_(0) {;}
00052     MixItr(typename std::vector<T>::const_iterator it) : pMixItr_(it),nrDets_(0),first_(true),internalCtr_(0) {;}
00053     MixItr(MixCollection *shc, int nrDets) :     
00054       mixCol_(shc),nrDets_(nrDets),first_(true),iSignal_(0),iPileup_(0),internalCtr_(0) {;}
00055 
00056 
00058     virtual ~MixItr() {;}
00059 
00061     const T* operator->() const { return pMixItr_.operator->(); }
00062     const T& operator*() const {return pMixItr_.operator*(); }
00063     MixItr operator++ () {return next();}
00064     MixItr operator++ (int) {return next();}
00065     bool operator!= (const MixItr& itr){return pMixItr_!=itr.pMixItr_;}
00066 
00068     int bunch() const {
00069       if (trigger_) return 0;
00070       int bcr= myCF_->getBunchCrossing(internalCtr_);
00071       return bcr;
00072     }
00073 
00074     bool getTrigger() const {return trigger_;}
00075 
00076     int getSourceType() const {return (getTrigger() ? -1 : myCF_->getSourceType(internalCtr_));}
00077 
00078   private:
00079 
00080     typename std::vector<T>::const_iterator pMixItr_;
00081     typename std::vector<T>::const_iterator pMixItrEnd_;
00082 
00083     const CrossingFrame<T> *    myCF_;
00084     MixCollection *mixCol_;
00085     int nrDets_;
00086     bool first_;
00087     int iSignal_, iPileup_;
00088     bool trigger_;
00089     unsigned int internalCtr_;
00090     
00091     MixItr next();
00092     void reset() {;}
00093     bool getNewSignal(typename std::vector<T>::const_iterator &first,typename std::vector<T>::const_iterator &last);
00094 
00095     bool  getNewPileups(typename std::vector<T>::const_iterator &first,typename std::vector<T>::const_iterator &last) ;
00096   };
00097 
00098   typedef MixItr iterator;
00099   iterator begin();
00100   iterator end() ;
00101 
00102  private:
00103   void init( const range bunchRange);
00104 
00105   range bunchRange_;
00106   bool inRegistry_;
00107   int nrDets_;
00108 
00109   std::vector<const CrossingFrame<T> *> crossingFrames_;
00110 
00111 };
00112 
00113 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00114 //
00115 // Exceptions
00116 //
00117 #include "FWCore/Utilities/interface/Exception.h"
00118 template <class T> 
00119 MixCollection<T>::MixCollection() : 
00120   bunchRange_(0,0), inRegistry_(false), nrDets_(0)
00121 {
00122   crossingFrames_.push_back(NULL);
00123 }
00124 
00125 template <class T> 
00126 MixCollection<T>::MixCollection(const CrossingFrame<T> *cf,const std::pair<int,int> bunchRange) : 
00127   inRegistry_(false),nrDets_(0) 
00128 {
00129   nrDets_=1;
00130   inRegistry_=true;
00131   if (cf) {
00132     crossingFrames_.push_back(cf);
00133     init(bunchRange);
00134   }
00135   else std::cout <<"Could not construct MixCollection for "<<typeid(T).name() <<", pointer to CrossingFrame invalid!"<<std::endl;
00136 } 
00137 
00138 template <class T> 
00139 MixCollection<T>::MixCollection(std::vector<const CrossingFrame<T> *> cfs, const std::pair<int,int> bunchRange) :  inRegistry_(false) , nrDets_(0)
00140 {
00141   // first, verify that all CrossingFrames have the same bunchrange
00142   range bR=cfs[0]->getBunchRange();
00143   for (unsigned int i=1;i<cfs.size();++i) {
00144     if (bR!= cfs[i]->getBunchRange()) throw cms::Exception("Incompatible CrossingFrames")<<"You gave as input CrossingFrames with different bunchRanges!";
00145   }
00146 
00147   //set necessary variables
00148   for (unsigned int i=0;i<cfs.size();++i) {
00149     nrDets_++;
00150     crossingFrames_.push_back(cfs[i]);
00151     inRegistry_=true;  // true if at least one is present
00152   }
00153 
00154   init(bunchRange);
00155 }
00156 
00157 template <class T> 
00158 void MixCollection<T>::init( const std::pair<int,int> bunchRange) {
00159 
00160   bunchRange_=bunchRange;
00161 
00162   //verify whether bunchrange is ok
00163   // in case of several crossingFrames, we have verified before that they have the same bunchrange
00164   range defaultrange=crossingFrames_[0]->getBunchRange();
00165   if (bunchRange_==range(-999,999)) bunchRange_=defaultrange;
00166   else if (bunchRange_!=defaultrange ) {
00167     int first=defaultrange.first;
00168     int last = defaultrange.second;
00169     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";
00170     bunchRange_=range(first,last);
00171   }
00172 }
00173 
00174 template <class T>  int  MixCollection<T>::sizePileup() const {
00175   // get size cumulated for all subdetectors
00176   int s=0;
00177   for (int i=0;i<nrDets_;++i) {
00178     s+=crossingFrames_[i]->getNrPileups();
00179   }  return s;
00180 }
00181 
00182 template <class T>  int  MixCollection<T>::sizeSignal() const {
00183   int s=0;
00184   for (int i=0;i<nrDets_;++i) {
00185     s+=crossingFrames_[i]->getNrSignals();
00186   }
00187   return s;
00188 }
00189 
00190 template <class T>
00191 bool MixCollection<T>::MixItr::getNewSignal(typename std::vector<T>::const_iterator &first,typename std::vector<T>::const_iterator &last) {
00192   // gets the next signal collection with non-zero size
00193 
00194   while (iSignal_<nrDets_) {
00195     mixCol_->crossingFrames_[iSignal_]->getSignal(first,last);
00196     myCF_=mixCol_->crossingFrames_[iSignal_];
00197     iSignal_++;
00198     if (first != last) return true;
00199   }
00200   return false;
00201 }
00202 
00203 template <class T>
00204 bool  MixCollection<T>::MixItr::getNewPileups(typename std::vector<T>::const_iterator &first,typename std::vector<T>::const_iterator &last) {
00205 
00206   // gets the next pileup collection , changing subdet if necessary
00207   while (iPileup_<nrDets_) {
00208     mixCol_-> crossingFrames_[iPileup_]->getPileups(first,last);
00209     int s=0;
00210     for (typename std::vector<T>::const_iterator it=first;it!= last ;it++) {
00211       s++;
00212     }
00213     myCF_=mixCol_->crossingFrames_[iPileup_];
00214     iPileup_++;
00215     if (first!=last) return true;
00216   }
00217   return false;
00218 }
00219 
00220 template <class T>
00221 typename MixCollection<T>::MixItr MixCollection<T>::MixItr::next() {
00222 
00223   // initialisation
00224   if (first_) {
00225     first_=false;
00226     trigger_=true;
00227   } else {
00228     if (!trigger_) internalCtr_++;
00229     if (++pMixItr_!=pMixItrEnd_) return *this;
00230   }
00231 
00232   // we have an end condition, look whether there are more collections
00233   bool ok;
00234   if (trigger_) {
00235     ok=this->getNewSignal(pMixItr_,pMixItrEnd_);
00236     if (ok) return *this;
00237     trigger_=false;
00238   } 
00239   ok=this->getNewPileups(pMixItr_,pMixItrEnd_);
00240   if (ok) {
00241     internalCtr_=0;
00242     return *this;
00243   }
00244   else {
00245     return mixCol_->end();
00246   }
00247 }
00248 
00249 template <class T>
00250 typename MixCollection<T>::MixItr MixCollection<T>::begin() {
00251   return MixItr(this,nrDets_)++;
00252 }
00253 
00254 template <class T>
00255 typename  MixCollection<T>::MixItr MixCollection<T>::end() {
00256   typename std::vector<T>::const_iterator first;
00257   typename std::vector<T>::const_iterator last;
00258   crossingFrames_[nrDets_-1]->getPileups(first, last);
00259   return last;
00260 }
00261 
00262 #include<iosfwd>
00263 #include<iostream>
00264 template <class T>
00265 std::ostream &operator<<(std::ostream& o, const MixCollection<T>& col)
00266 {
00267   o << "MixCollection with bunchRange: "<<(col.bunchrange()).first<< "," << (col.bunchrange()).second <<" size of signal: "<<col.sizeSignal() <<" ,size of pileup: "<<col.sizePileup();
00268 
00269 
00270   return o;
00271 }
00272 
00273 #endif
00274 

Generated on Tue Jun 9 17:46:32 2009 for CMSSW by  doxygen 1.5.4