CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/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       m_subdetId(0), m_stride(0),
00055       m_ids(), m_data(){}
00056     
00057     explicit DataFrameContainer(size_t istride, int isubdet=0, size_t isize=0) :
00058       m_subdetId(isubdet), m_stride(istride),
00059       m_ids(isize), m_data(isize*m_stride){}
00060     
00061     void swap(DataFrameContainer & rh) {
00062       std::swap(m_subdetId,rh.m_subdetId);
00063       std::swap(m_stride,rh.m_stride);
00064       m_ids.swap(rh.m_ids);
00065       m_data.swap(rh.m_data);
00066     }
00067     
00068     DataFrameContainer& operator=(DataFrameContainer const& rhs) {
00069       DataFrameContainer temp(rhs);
00070       this->swap(temp);
00071       return *this;
00072     }
00073 
00074     void swap(IdContainer & iic, DataContainer & idc) {
00075       m_ids.swap(iic);
00076       m_data.swap(idc);
00077     }
00078     
00079     void reserve(size_t isize) {
00080       m_ids.reserve(isize);
00081       m_data.reserve(isize*m_stride);
00082     }
00083     
00084     void resize(size_t isize) {
00085       m_ids.resize(isize);
00086       m_data.resize(isize*m_stride);
00087     }
00088 
00089     void sort();
00090     
00091     // FIXME not sure what the best way to add one cell to cont
00092     void push_back(id_type iid, data_type const * idata) {
00093       m_ids.push_back(iid);
00094       size_t cs = m_data.size();
00095       m_data.resize(m_data.size()+m_stride);
00096       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00097     }
00098     //make space for it
00099     void push_back(id_type iid) {
00100       m_ids.push_back(iid);
00101       m_data.resize(m_data.size()+m_stride);
00102     }
00103     // overwrite back (very ad hoc interface...)
00104     void set_back(id_type iid, data_type const * idata) {
00105       m_ids.back() = iid;
00106       size_t cs = m_data.size()-m_stride;
00107       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00108     }
00109     void set_back(id_type iid) {
00110       m_ids.back() = iid;
00111     }
00112     void set_back(data_type const * idata) {
00113       size_t cs = m_data.size()-m_stride;
00114       std::copy(idata,idata+m_stride,m_data.begin()+cs);
00115     }
00116 
00117     DataFrame back() {
00118       return DataFrame(*this,size()-1);
00119     }
00120 
00121     void pop_back() {
00122       m_ids.resize(m_ids.size()-1);
00123       m_data.resize(m_data.size()-m_stride);
00124     }
00125 
00126     //---------------------------------------------------------
00127     
00128     IterPair pair(size_t i) {
00129       return IterPair(m_ids.begin()+i,m_data.begin()+i*m_stride);
00130     }
00131     
00132     const_IterPair pair(size_t i) const {
00133       return const_IterPair(m_ids.begin()+i,m_data.begin()+i*m_stride);
00134     }
00135     
00136     DataFrame operator[](size_t i) {
00137       return DataFrame(*this,i);
00138     }
00139     
00140     DataFrame operator[](size_t i) const {
00141       return DataFrame(*this,i);
00142     }
00143     
00144     // slow interface
00145     const_iterator find(id_type i) const {
00146       const_IdIter p = std::lower_bound(m_ids.begin(),m_ids.end(),i);
00147       return (p==m_ids.end() || (*p)!=i) ? end() :
00148         boost::make_transform_iterator(boost::counting_iterator<int>(p-m_ids.begin()),
00149                                        IterHelp(*this));
00150     }
00151     
00152     const_iterator begin() const {
00153       return  boost::make_transform_iterator(boost::counting_iterator<int>(0),
00154                                              IterHelp(*this));
00155     }
00156     const_iterator end() const {
00157       return  boost::make_transform_iterator(boost::counting_iterator<int>(size()),
00158                                              IterHelp(*this));
00159     }
00160     
00161     
00162     int subdetId() const { return m_subdetId; }
00163 
00164     size_type stride() const { return m_stride; }
00165     
00166     bool empty() const { return m_ids.empty();}
00167 
00168     size_type size() const { return m_ids.size();}
00169     
00170     data_type operator()(size_t cell, size_t frame) const {
00171       return m_data[cell*m_stride+frame];
00172     }
00173     
00174     data_type const * frame(size_t cell) const {
00175       return &m_data[cell*m_stride];
00176     }
00177     
00178     id_type id(size_t cell) const {
00179       return m_ids[cell];
00180     }
00181     
00182     // IdContainer const & ids() const { return m_ids;}
00183     // DataContainer const & data() const { return  m_data;}
00184     
00185   private:
00186     // subdetector id (as returned by  DetId::subdetId())
00187     int m_subdetId;
00188 
00189     // can be a enumerator, or a template argument
00190     size_type m_stride;
00191     
00192     IdContainer m_ids;
00193     DataContainer m_data;
00194     
00195   };
00196   
00197   inline
00198   DataFrame::DataFrame(DataFrameContainer const & icont,
00199                        size_type i) :
00200     m_id(icont.id(i)), m_data(icont.frame(i)), m_size(icont.stride()){}
00201 
00202   inline
00203   void DataFrame::set(DataFrameContainer const & icont,
00204                       size_type i) {
00205     m_id=icont.id(i); 
00206     m_data=icont.frame(i);
00207     m_size=icont.stride();
00208   }
00209   
00210   // Free swap function
00211   inline
00212   void
00213   swap(DataFrameContainer& lhs, DataFrameContainer& rhs) {
00214     lhs.swap(rhs);
00215   }
00216 
00217 }
00218 
00219 // The standard allows us to specialize std::swap for non-templates.
00220 // This ensures that DataFrameContainer::swap() will be used in algorithms.
00221 
00222 namespace std {
00223   template <> inline void swap(edm::DataFrameContainer& lhs, edm::DataFrameContainer& rhs) {  
00224     lhs.swap(rhs);
00225   }
00226 }
00227 
00228 #endif // DataFormats_Common_DataFrameContainer_h