CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/DataFormats/Common/interface/DataFrameContainer.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_DataFrameContainer_h
00002 #define DataFormats_Common_DataFrameContainer_h
00003 
00004 #include "DataFormats/Common/interface/DataFrame.h"
00005 
00006 #include <boost/iterator/transform_iterator.hpp>
00007 #include <boost/iterator/counting_iterator.hpp>
00008 
00009 #include<vector>
00010 #include<algorithm>
00011 
00012 namespace edm {
00013 
00024   class DataFrameContainer {
00025   public:
00026     typedef unsigned int size_type; // for persistency
00027     typedef unsigned int id_type;
00028     typedef unsigned short data_type;
00029     typedef std::vector<id_type> IdContainer;
00030     typedef std::vector<data_type> DataContainer;
00031     typedef std::vector<id_type>::iterator IdIter;
00032     typedef std::vector<data_type>::iterator DataIter;
00033     typedef std::pair<IdIter,DataIter> IterPair;
00034     typedef std::vector<id_type>::const_iterator const_IdIter;
00035     typedef std::vector<data_type>::const_iterator const_DataIter;
00036     typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
00037     
00038     struct IterHelp {
00039       typedef DataFrame result_type;
00040       IterHelp(DataFrameContainer const & iv) : v(iv){}
00041       
00042       DataFrame const & operator()(int i) const {
00043         frame.set(v,i);
00044         return frame;
00045       } 
00046     private:
00047       DataFrameContainer const & v;
00048       mutable DataFrame frame;
00049     };
00050     
00051     typedef boost::transform_iterator<IterHelp,boost::counting_iterator<int> > const_iterator;
00052     
00053     DataFrameContainer(){}
00054     
00055     explicit DataFrameContainer(size_t istride, int isubdet=0, size_t isize=0) :
00056       m_subdetId(isubdet), m_stride(istride),
00057       m_ids(isize), m_data(isize*m_stride){}
00058     
00059     void swap(DataFrameContainer & rh) {
00060       std::swap(m_subdetId,rh.m_subdetId);
00061       std::swap(m_stride,rh.m_stride);
00062       m_ids.swap(rh.m_ids);
00063       m_data.swap(rh.m_data);
00064     }
00065     
00066     DataFrameContainer& operator=(DataFrameContainer const& rhs) {
00067       DataFrameContainer temp(rhs);
00068       this->swap(temp);
00069       return *this;
00070     }
00071 
00072     void swap(IdContainer & iic, DataContainer & idc) {
00073       m_ids.swap(iic);
00074       m_data.swap(idc);
00075     }
00076     
00077     void reserve(size_t isize) {
00078       m_ids.reserve(isize);
00079       m_data.reserve(isize*m_stride);
00080     }
00081     
00082     void resize(size_t isize) {
00083       m_ids.resize(isize);
00084       m_data.resize(isize*m_stride);
00085     }
00086 
00087     void sort();
00088     
00089     // FIXME not sure what the best way to add one cell to cont
00090     void push_back(id_type iid, data_type const * idata) {
00091       m_ids.push_back(iid);
00092       size_t cs = m_data.size();
00093       m_data.resize(m_data.size()+m_stride);
00094       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00095     }
00096     //make space for it
00097     void push_back(id_type iid) {
00098       m_ids.push_back(iid);
00099       m_data.resize(m_data.size()+m_stride);
00100     }
00101     // overwrite back (very ad hoc interface...)
00102     void set_back(id_type iid, data_type const * idata) {
00103       m_ids.back() = iid;
00104       size_t cs = m_data.size()-m_stride;
00105       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00106     }
00107     void set_back(id_type iid) {
00108       m_ids.back() = iid;
00109     }
00110     void set_back(data_type const * idata) {
00111       size_t cs = m_data.size()-m_stride;
00112       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00113     }
00114 
00115     DataFrame back() {
00116       return DataFrame(*this,size()-1);
00117     }
00118 
00119     void pop_back() {
00120       m_ids.resize(m_ids.size()-1);
00121       m_data.resize(m_data.size()-m_stride);
00122     }
00123 
00124     //---------------------------------------------------------
00125     
00126     IterPair pair(size_t i) {
00127       return IterPair(m_ids.begin()+i,m_data.begin()+i*m_stride);
00128     }
00129     
00130     const_IterPair pair(size_t i) const {
00131       return const_IterPair(m_ids.begin()+i,m_data.begin()+i*m_stride);
00132     }
00133     
00134     DataFrame operator[](size_t i) {
00135       return DataFrame(*this,i);
00136     }
00137     
00138     DataFrame operator[](size_t i) const {
00139       return DataFrame(*this,i);
00140     }
00141     
00142     // slow interface
00143     const_iterator find(id_type i) const {
00144       const_IdIter p = std::lower_bound(m_ids.begin(),m_ids.end(),i);
00145       return (p==m_ids.end() || (*p)!=i) ? end() :
00146         boost::make_transform_iterator(boost::counting_iterator<int>(p-m_ids.begin()),
00147                                        IterHelp(*this));
00148     }
00149     
00150     const_iterator begin() const {
00151       return  boost::make_transform_iterator(boost::counting_iterator<int>(0),
00152                                              IterHelp(*this));
00153     }
00154     const_iterator end() const {
00155       return  boost::make_transform_iterator(boost::counting_iterator<int>(size()),
00156                                              IterHelp(*this));
00157     }
00158     
00159     
00160     int subdetId() const { return m_subdetId; }
00161 
00162     size_type stride() const { return m_stride; }
00163     
00164     bool empty() const { return m_ids.empty();}
00165 
00166     size_type size() const { return m_ids.size();}
00167     
00168     data_type operator()(size_t cell, size_t frame) const {
00169       return m_data[cell*m_stride+frame];
00170     }
00171     
00172     data_type const * frame(size_t cell) const {
00173       return &m_data[cell*m_stride];
00174     }
00175     
00176     id_type id(size_t cell) const {
00177       return m_ids[cell];
00178     }
00179     
00180     // IdContainer const & ids() const { return m_ids;}
00181     // DataContainer const & data() const { return  m_data;}
00182     
00183   private:
00184     // subdetector id (as returned by  DetId::subdetId())
00185     int m_subdetId;
00186 
00187     // can be a enumerator, or a template argument
00188     size_type m_stride;
00189     
00190     IdContainer m_ids;
00191     DataContainer m_data;
00192     
00193   };
00194   
00195   inline
00196   DataFrame::DataFrame(DataFrameContainer const & icont,
00197                        size_type i) :
00198     m_id(icont.id(i)), m_data(icont.frame(i)), m_size(icont.stride()){}
00199 
00200   inline
00201   void DataFrame::set(DataFrameContainer const & icont,
00202                       size_type i) {
00203     m_id=icont.id(i); 
00204     m_data=icont.frame(i);
00205     m_size=icont.stride();
00206   }
00207   
00208   // Free swap function
00209   inline
00210   void
00211   swap(DataFrameContainer& lhs, DataFrameContainer& rhs) {
00212     lhs.swap(rhs);
00213   }
00214 
00215 }
00216 
00217 // The standard allows us to specialize std::swap for non-templates.
00218 // This ensures that DataFrameContainer::swap() will be used in algorithms.
00219 
00220 namespace std {
00221   template <> inline void swap(edm::DataFrameContainer& lhs, edm::DataFrameContainer& rhs) {  
00222     lhs.swap(rhs);
00223   }
00224 }
00225 
00226 #endif // DataFormats_Common_DataFrameContainer_h