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
00027 bool inRegistry() const {return inRegistry_;}
00028
00029
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!";
00032 int n=ip;
00033
00034
00035
00036
00037
00038
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
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
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
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_;
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
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
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
00164 for (unsigned int i=0;i<cfs.size();++i) {
00165 nrDets_++;
00166 crossingFrames_.push_back(cfs[i]);
00167 inRegistry_=true;
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
00179
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
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
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
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
00240 if (first_) {
00241 first_=false;
00242 trigger_=true;
00243 } else {
00244 if (!trigger_) internalCtr_++;
00245 if (++pMixItr_!=pMixItrEnd_) return *this;
00246 }
00247
00248
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
00258 typename std::vector<const T *>::const_iterator dbIt;
00259
00260
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