CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:28:35 2009 for CMSSW by  doxygen 1.5.4