CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimDataFormats/CrossingFrame/interface/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>=(unsigned int)size()) throw cms::Exception("BadIndex")<<"MixCollection::getObject called with an invalid index!"; // ip >= 0, since ip is unsigned
00032      int n=ip;
00033 /*
00034 -    int iframe=0;
00035 -    for (unsigned int ii=0;ii<crossingFrames_.size();++ii) {
00036 -      iframe=ii;
00037 -      int s=crossingFrames_[iframe]->getNrSignals()+crossingFrames_[iframe]->getNrPileups();
00038 -      if (n<s) break;
00039 */
00040     for (unsigned int iframe=0;iframe<crossingFrames_.size();++iframe) {
00041       int s=crossingFrames_[iframe]->getNrSignals();
00042       if (n<s) return crossingFrames_[iframe]->getObject(n);
00043        n=n-s;
00044      }
00045 /*
00046     return crossingFrames_[iframe]->getObject(n);
00047 */
00048     for (unsigned int iframe=0;iframe<crossingFrames_.size();++iframe) {
00049       int s=crossingFrames_[iframe]->getNrSignals();
00050       int p=crossingFrames_[iframe]->getNrPileups();
00051       if (n<p) return crossingFrames_[iframe]->getObject(s+n);
00052       n=n-p;
00053     }
00054     throw cms::Exception("InternalError")<<"MixCollection::getObject reached impossible condition"; 
00055    }
00056 
00057   class MixItr;
00058   friend class MixItr;
00059 
00060   // nested class for iterator
00061   class MixItr {
00062   public:
00063 
00065     MixItr():first_(true), internalCtr_(0) {;}
00066     MixItr(typename std::vector<const T *>::const_iterator it) : pMixItr_(it),nrDets_(0),first_(true),internalCtr_(0) {;}
00067        MixItr(MixCollection *shc, int nrDets) :     
00068        mixCol_(shc),nrDets_(nrDets),first_(true),iSignal_(0),iPileup_(0),internalCtr_(0) {;}
00069 
00070 
00072     virtual ~MixItr() {;}
00073 
00075     // default version valid for HepMCProduct
00076     const T* operator->() const { return *(pMixItr_.operator->()); }
00077     const T& operator*() const {return *(pMixItr_.operator*()); }
00078     MixItr operator++ () {return next();}
00079     MixItr operator++ (int) {return next();}
00080     bool operator!= (const MixItr& itr){return pMixItr_!=itr.pMixItr_;}
00081 
00083     int bunch() const {
00084       if (trigger_) return 0;
00085       int bcr= myCF_->getBunchCrossing(internalCtr_);
00086       return bcr;
00087     }
00088 
00089     bool getTrigger() const {return trigger_;}
00090 
00091     int getSourceType() const {return (getTrigger() ? -1 : myCF_->getSourceType(internalCtr_));}
00092     int getPileupEventNr() const {return (getTrigger() ? 0 : myCF_->getPileupEventNr(internalCtr_));}
00093 
00094   private:
00095 
00096     typename std::vector<const T *>::const_iterator pMixItr_;
00097     typename std::vector<const T *>::const_iterator pMixItrEnd_;
00098 
00099     const CrossingFrame<T> *    myCF_;
00100     MixCollection *mixCol_;
00101     int nrDets_;
00102     bool first_;
00103     int iSignal_, iPileup_;
00104     bool trigger_;
00105     unsigned int internalCtr_;  //this is the internal counter pointing into the vector of piled up objects
00106     
00107     MixItr next();
00108     void reset() {;}
00109     bool getNewSignal(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last);
00110 
00111     bool  getNewPileups(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) ;
00112   };
00113 
00114   typedef MixItr iterator;
00115   iterator begin();
00116   iterator end() ;
00117 
00118  private:
00119   void init( const range bunchRange);
00120 
00121   range bunchRange_;
00122   bool inRegistry_;
00123   int nrDets_;
00124 
00125   std::vector<const CrossingFrame<T> *> crossingFrames_;
00126 
00127 };
00128 
00129 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00130 //
00131 // Exceptions
00132 //
00133 #include "FWCore/Utilities/interface/Exception.h"
00134 template <class T> 
00135 MixCollection<T>::MixCollection() : 
00136   bunchRange_(0,0), inRegistry_(false), nrDets_(0)
00137 {
00138   crossingFrames_.push_back(NULL);
00139 }
00140 
00141 template <class T> 
00142 MixCollection<T>::MixCollection(const CrossingFrame<T> *cf,const std::pair<int,int> bunchRange) : 
00143   inRegistry_(false),nrDets_(0) 
00144 {
00145   nrDets_=1;
00146   inRegistry_=true;
00147   if (cf) {
00148     crossingFrames_.push_back(cf);
00149     init(bunchRange);
00150   }
00151   else std::cout <<"Could not construct MixCollection for "<<typeid(T).name() <<", pointer to CrossingFrame invalid!"<<std::endl;
00152 } 
00153 
00154 template <class T> 
00155 MixCollection<T>::MixCollection(std::vector<const CrossingFrame<T> *> cfs, const std::pair<int,int> bunchRange) :  inRegistry_(false) , nrDets_(0)
00156 {
00157   // first, verify that all CrossingFrames have the same bunchrange
00158   range bR=cfs[0]->getBunchRange();
00159   for (unsigned int i=1;i<cfs.size();++i) {
00160     if (bR!= cfs[i]->getBunchRange()) throw cms::Exception("Incompatible CrossingFrames")<<"You gave as input CrossingFrames with different bunchRanges!";
00161   }
00162 
00163   //set necessary variables
00164   for (unsigned int i=0;i<cfs.size();++i) {
00165     nrDets_++;
00166     crossingFrames_.push_back(cfs[i]);
00167     inRegistry_=true;  // true if at least one is present
00168   }
00169 
00170   init(bunchRange);
00171 }
00172 
00173 template <class T> 
00174 void MixCollection<T>::init( const std::pair<int,int> bunchRange) {
00175 
00176   bunchRange_=bunchRange;
00177 
00178   //verify whether bunchrange is ok
00179   // in case of several crossingFrames, we have verified before that they have the same bunchrange
00180   range defaultrange=crossingFrames_[0]->getBunchRange();
00181   if (bunchRange_==range(-999,999)) bunchRange_=defaultrange;
00182   else if (bunchRange_!=defaultrange ) {
00183     int first=defaultrange.first;
00184     int last = defaultrange.second;
00185     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";
00186     bunchRange_=range(first,last);
00187   }
00188 }
00189 
00190 template <class T>  int  MixCollection<T>::sizePileup() const {
00191   // get size cumulated for all subdetectors
00192   int s=0;
00193   for (int i=0;i<nrDets_;++i) {
00194     s+=crossingFrames_[i]->getNrPileups();
00195   }  return s;
00196 }
00197 
00198 template <class T>  int  MixCollection<T>::sizeSignal() const {
00199   int s=0;
00200   for (int i=0;i<nrDets_;++i) {
00201     s+=crossingFrames_[i]->getNrSignals();
00202   }
00203   return s;
00204 }
00205 
00206 template <class T>
00207 bool MixCollection<T>::MixItr::getNewSignal(typename std::vector<const T *>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) {
00208   // gets the next signal collection with non-zero size
00209 
00210   while (iSignal_<nrDets_) {
00211     mixCol_->crossingFrames_[iSignal_]->getSignal(first,last);
00212     myCF_=mixCol_->crossingFrames_[iSignal_];
00213     iSignal_++;
00214     if (first != last) return true;
00215   }
00216   return false;
00217 }
00218 
00219 template <class T>
00220 bool  MixCollection<T>::MixItr::getNewPileups(typename std::vector<const T*>::const_iterator &first,typename std::vector<const T *>::const_iterator &last) {
00221 
00222   // gets the next pileup collection , changing subdet if necessary
00223   while (iPileup_<nrDets_) {
00224     mixCol_-> crossingFrames_[iPileup_]->getPileups(first,last);
00225     int s=0;
00226     for (typename std::vector<const T*>::const_iterator it=first;it!= last ;it++) {
00227       s++;
00228     }
00229     myCF_=mixCol_->crossingFrames_[iPileup_];
00230     iPileup_++;
00231     if (first!=last) return true;
00232   }
00233   return false;
00234 }
00235 
00236 template <class T>
00237 typename MixCollection<T>::MixItr MixCollection<T>::MixItr::next() {
00238 
00239   // initialisation
00240   if (first_) {
00241     first_=false;
00242     trigger_=true;
00243   } else {
00244     if (!trigger_) internalCtr_++;
00245     if (++pMixItr_!=pMixItrEnd_) return *this;
00246   }
00247 
00248   // we have an end condition, look whether there are more collections
00249   bool ok;
00250   if (trigger_) {
00251     ok=this->getNewSignal(pMixItr_,pMixItrEnd_);
00252     if (ok) return *this;
00253     trigger_=false;
00254   } 
00255   ok=this->getNewPileups(pMixItr_,pMixItrEnd_);
00256   if (ok) {
00257     // debug print start
00258     typename std::vector<const T *>::const_iterator dbIt;
00259     //    for (dbIt=pMixItr_;dbIt!=pMixItrEnd_;++dbIt)  printf("Found pointer %p\n",(*dbIt));fflush(stdout);
00260     // debug print end
00261     internalCtr_=0;
00262     return *this;
00263   }
00264   else {
00265     return mixCol_->end();
00266   }
00267 }
00268 
00269 template <class T>
00270 typename MixCollection<T>::MixItr MixCollection<T>::begin() {
00271   return MixItr(this,nrDets_)++;
00272 }
00273 
00274 template <class T>
00275 typename  MixCollection<T>::MixItr MixCollection<T >::end() {
00276   typename std::vector<const T *>::const_iterator first;
00277   typename std::vector<const T*>::const_iterator last;
00278   crossingFrames_[nrDets_-1]->getPileups(first, last);
00279   return last;
00280 }
00281 
00282 #include<iosfwd>
00283 #include<iostream>
00284 template <class T>
00285 std::ostream &operator<<(std::ostream& o, const MixCollection<T>& col)
00286 {
00287   o << "MixCollection with bunchRange: "<<(col.bunchrange()).first<< "," << (col.bunchrange()).second <<" size of signal: "<<col.sizeSignal() <<" ,size of pileup: "<<col.sizePileup();
00288 
00289 
00290   return o;
00291 }
00292 
00293 #endif
00294