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<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
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
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
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
00148 for (unsigned int i=0;i<cfs.size();++i) {
00149 nrDets_++;
00150 crossingFrames_.push_back(cfs[i]);
00151 inRegistry_=true;
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
00163
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
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
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
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
00224 if (first_) {
00225 first_=false;
00226 trigger_=true;
00227 } else {
00228 if (!trigger_) internalCtr_++;
00229 if (++pMixItr_!=pMixItrEnd_) return *this;
00230 }
00231
00232
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