CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/Common/interface/DetSetVectorNew.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_DetSetVectorNew_h
00002 #define DataFormats_Common_DetSetVectorNew_h
00003 
00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00005 // #include "DataFormats/Common/interface/DetSet.h"  // to get det_id_type
00006 #include "DataFormats/Common/interface/DetSetNew.h"
00007 #include "DataFormats/Common/interface/traits.h"
00008 
00009 #include <boost/iterator_adaptors.hpp>
00010 #include <boost/iterator/transform_iterator.hpp>
00011 #include <boost/iterator/counting_iterator.hpp>
00012 #include <boost/any.hpp>
00013 #include "boost/shared_ptr.hpp"
00014 
00015 
00016 #include<vector>
00017 
00018 namespace edm { namespace refhelper { template<typename T> struct FindForNewDetSetVector; } }
00019 
00020 //FIXME remove New when ready
00021 namespace edmNew {
00022   typedef uint32_t det_id_type;
00023 
00024   namespace dslv {
00025     template< typename T> class LazyGetter;
00026   }
00027 
00028   /* transient component of DetSetVector
00029    * for pure conviniency of dictioanary declaration
00030    */
00031   namespace dstvdetails {
00032     struct DetSetVectorTrans {
00033       DetSetVectorTrans(): filling(false){}
00034       bool filling;
00035       boost::any getter;
00036 
00037       typedef unsigned int size_type; // for persistency
00038       typedef unsigned int id_type;
00039 
00040       struct Item {
00041         Item(id_type i=0, int io=-1, size_type is=0) : id(i), offset(io), size(is){}
00042         id_type id;
00043         int offset;
00044         size_type size;
00045         bool operator<(Item const &rh) const { return id<rh.id;}
00046         operator id_type() const { return id;}
00047       };
00048 
00049     };
00050     void errorFilling();
00051     void errorIdExists(det_id_type iid);
00052     void throw_range(det_id_type iid);
00053    }
00054 
00065   template<typename T>
00066   class DetSetVector  : private dstvdetails::DetSetVectorTrans {
00067   public:
00068     typedef dstvdetails::DetSetVectorTrans Trans;
00069     typedef Trans::Item Item;
00070     typedef unsigned int size_type; // for persistency
00071     typedef unsigned int id_type;
00072     typedef T data_type;
00073     typedef edmNew::DetSetVector<T> self;
00074     typedef edmNew::DetSet<T> DetSet;
00075     typedef dslv::LazyGetter<T> Getter;
00076     // FIXME not sure make sense....
00077     typedef DetSet value_type;
00078     typedef id_type key_type;
00079 
00080 
00081     typedef std::vector<Item> IdContainer;
00082     typedef std::vector<data_type> DataContainer;
00083     typedef typename IdContainer::iterator IdIter;
00084     typedef typename std::vector<data_type>::iterator DataIter;
00085     typedef std::pair<IdIter,DataIter> IterPair;
00086     typedef typename IdContainer::const_iterator const_IdIter;
00087     typedef typename std::vector<data_type>::const_iterator const_DataIter;
00088     typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
00089 
00090     typedef typename edm::refhelper::FindForNewDetSetVector<data_type>  RefFinder;
00091     
00092     struct IterHelp {
00093       typedef DetSet result_type;
00094       IterHelp(DetSetVector<T> const & iv) : v(&iv){}
00095       
00096        result_type & operator()(Item const& item) const {
00097         detset.set(*v,item);
00098         return detset;
00099       } 
00100     private:
00101       DetSetVector<T> const * v;
00102       mutable result_type detset;
00103     };
00104     
00105     typedef boost::transform_iterator<IterHelp,const_IdIter> const_iterator;
00106     typedef std::pair<const_iterator,const_iterator> Range;
00107 
00108     /* fill the lastest inserted DetSet
00109      */
00110     class FastFiller {
00111     public:
00112       typedef typename DetSetVector<T>::data_type value_type;
00113       typedef typename DetSetVector<T>::id_type key_type;
00114       typedef typename DetSetVector<T>::id_type id_type;
00115       typedef typename DetSetVector<T>::size_type size_type;
00116 
00117       FastFiller(DetSetVector<T> & iv, id_type id, bool isaveEmpty=false) : 
00118         v(iv), item(v.push_back(id)), saveEmpty(isaveEmpty) {
00119         if (v.filling) dstvdetails::errorFilling();
00120         v.filling=true;
00121       }
00122       FastFiller(DetSetVector<T> & iv, typename DetSetVector<T>::Item & it, bool isaveEmpty=false) : 
00123         v(iv), item(it), saveEmpty(isaveEmpty) {
00124         if (v.filling) dstvdetails::errorFilling();
00125         v.filling=true;
00126       }
00127       ~FastFiller() {
00128         if (!saveEmpty && item.size==0) {
00129           v.pop_back(item.id);
00130         }
00131         v.filling=false;
00132       }
00133       
00134       void abort() {
00135         v.pop_back(item.id);
00136         saveEmpty=true; // avoid mess in destructor
00137       }
00138 
00139       void reserve(size_type s) {
00140         v.m_data.reserve(item.offset+s);
00141       }
00142 
00143       void resize(size_type s) {
00144         v.m_data.resize(item.offset+s);
00145         item.size=s;
00146       }
00147 
00148       id_type id() const { return item.id;}
00149       size_type size() const { return item.size;}
00150       bool empty() const { return item.size==0;}
00151 
00152       data_type & operator[](size_type i) {
00153         return  v.m_data[item.offset+i];
00154       }
00155       DataIter begin() { return v.m_data.begin()+ item.offset;}
00156       DataIter end() { return v.m_data.end();}
00157 
00158       void push_back(data_type const & d) {
00159         v.m_data.push_back(d);
00160         item.size++;
00161       }
00162       data_type & back() { return v.m_data.back();}
00163       
00164     private:
00165       DetSetVector<T> & v;
00166       typename DetSetVector<T>::Item & item;
00167       bool saveEmpty;
00168     };
00169     friend class FastFiller;
00170 
00171     class FindForDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
00172     public:
00173         typedef FindForDetSetVector self;
00174         typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00175             return &(iContainer.m_data[iIndex]);
00176         }
00177     };
00178     friend class FindForDetSetVector;
00179 
00180     explicit DetSetVector(int isubdet=0) :
00181       m_subdetId(isubdet) {}
00182 
00183     DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter, const std::vector<det_id_type>& iDets,
00184                  int isubdet=0);
00185 
00186 
00187     ~DetSetVector() {
00188       // delete content if T is pointer...
00189     }
00190     
00191     void swap(DetSetVector & rh) {
00192       std::swap(m_subdetId,rh.m_subdetId);
00193       std::swap(m_ids,rh.m_ids);
00194       std::swap(m_data,rh.m_data);
00195     }
00196     
00197     void swap(IdContainer & iic, DataContainer & idc) {
00198       std::swap(m_ids,iic);
00199       std::swap(m_data,idc);
00200     }
00201     
00202     void reserve(size_t isize, size_t dsize) {
00203       m_ids.reserve(isize);
00204       m_data.reserve(dsize);
00205     }
00206     
00207     void resize(size_t isize, size_t dsize) {
00208       m_ids.resize(isize);
00209       m_data.resize(dsize);
00210     }
00211     
00212     // FIXME not sure what the best way to add one cell to cont
00213     DetSet insert(id_type iid, data_type const * idata, size_type isize) {
00214       Item & item = addItem(iid,isize);
00215       m_data.resize(m_data.size()+isize);
00216       std::copy(idata,idata+isize,m_data.begin()+item.offset);
00217      return DetSet(*this,item);
00218     }
00219     //make space for it
00220     DetSet insert(id_type iid, size_type isize) {
00221       Item & item = addItem(iid,isize);
00222       m_data.resize(m_data.size()+isize);
00223       return DetSet(*this,item);
00224     }
00225 
00226     // to be used with a FastFiller
00227     Item & push_back(id_type iid) {
00228       return addItem(iid,0);
00229     }
00230 
00231     // remove last entry (usually only if empty...)
00232     void pop_back(id_type iid) {
00233       const_IdIter p = findItem(iid);
00234       if (p==m_ids.end()) return; //bha!
00235       // sanity checks...  (shall we throw or assert?)
00236       if ((*p).size>0&& (*p).offset>-1 && 
00237           m_data.size()==(*p).offset+(*p).size)
00238         m_data.resize((*p).offset);
00239       m_ids.erase( m_ids.begin()+(p-m_ids.begin()));
00240     }
00241 
00242   private:
00243 
00244     Item & addItem(id_type iid,  size_type isize) {
00245       Item it(iid,size_type(m_data.size()),isize);
00246       IdIter p = std::lower_bound(m_ids.begin(),
00247                                   m_ids.end(),
00248                                   it);
00249       if (p!=m_ids.end() && !(it<*p)) dstvdetails::errorIdExists(iid);
00250       return *m_ids.insert(p,it);
00251     }
00252 
00253 
00254 
00255   public:
00256 
00257 
00258     //---------------------------------------------------------
00259     
00260     bool exists(id_type i) const  {
00261       return  findItem(i)!=m_ids.end(); 
00262     }
00263         
00264     bool isValid(id_type i) const {
00265       const_IdIter p = findItem(i);
00266       return p!=m_ids.end() && (*p).offset!=-1;
00267     }
00268 
00269     /*
00270     DetSet operator[](id_type i) {
00271       const_IdIter p = findItem(i);
00272       if (p==m_ids.end()) what???
00273       return DetSet(*this,p-m_ids.begin());
00274     }
00275     */
00276 
00277     
00278     DetSet operator[](id_type i) const {
00279       const_IdIter p = findItem(i);
00280       if (p==m_ids.end()) dstvdetails::throw_range(i);
00281       return DetSet(*this,*p);
00282     }
00283     
00284     // slow interface
00285     const_iterator find(id_type i) const {
00286       const_IdIter p = findItem(i);
00287       return (p==m_ids.end()) ? end() :
00288         boost::make_transform_iterator(p,
00289                                        IterHelp(*this));
00290     }
00291 
00292     // slow interface
00293     const_IdIter findItem(id_type i) const {
00294       std::pair<const_IdIter,const_IdIter> p =
00295         std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
00296       return (p.first!=p.second) ? p.first : m_ids.end();
00297     }
00298     
00299     const_iterator begin() const {
00300       return  boost::make_transform_iterator(m_ids.begin(),
00301                                              IterHelp(*this));
00302     }
00303 
00304     const_iterator end() const {
00305       return  boost::make_transform_iterator(m_ids.end(),
00306                                              IterHelp(*this));
00307     }
00308     
00309 
00310     // return an iterator range (implemented here to avoid dereference of detset)
00311     template<typename CMP>
00312     Range equal_range(id_type i, CMP cmp) const {
00313       std::pair<const_IdIter,const_IdIter> p =
00314         std::equal_range(m_ids.begin(),m_ids.end(),i,cmp);
00315       return  Range(boost::make_transform_iterator(p.first,IterHelp(*this)),
00316                     boost::make_transform_iterator(p.second,IterHelp(*this))
00317                     );
00318     }
00319     
00320     int subdetId() const { return m_subdetId; }
00321 
00322     bool empty() const { return m_ids.empty();}
00323 
00324 
00325     size_type dataSize() const { return m_data.size(); }
00326     
00327     size_type size() const { return m_ids.size();}
00328     
00329     //FIXME fast interfaces, not consistent with associative nature of container....
00330 
00331     data_type operator()(size_t cell, size_t frame) const {
00332       return m_data[m_ids[cell].offset+frame];
00333     }
00334     
00335     data_type const * data(size_t cell) const {
00336       return &m_data[m_ids[cell].offset];
00337     }
00338     
00339     size_type detsetSize(size_t cell) const { return  m_ids[cell].size; }
00340 
00341     id_type id(size_t cell) const {
00342       return m_ids[cell].id;
00343     }
00344 
00345     Item const & item(size_t cell) const {
00346       return m_ids[cell];
00347     }
00348 
00349     //------------------------------
00350 
00351     // IdContainer const & ids() const { return m_ids;}
00352     DataContainer const & data() const { return  m_data;}
00353 
00354 
00355     void update(Item const & item) const {
00356       const_cast<self*>(this)->updateImpl(const_cast<Item&>(item));
00357     }
00358    
00359     //Used by ROOT storage
00360     CMS_CLASS_VERSION(10)
00361 
00362   private:
00363 
00364     void updateImpl(Item & item);
00365     
00366   private:
00367     // subdetector id (as returned by  DetId::subdetId())
00368     int m_subdetId;
00369     
00370     
00371     IdContainer m_ids;
00372     DataContainer m_data;
00373     
00374   };
00375   
00376  namespace dslv {
00377     template< typename T>
00378     class LazyGetter {
00379     public:
00380       virtual ~LazyGetter() {}
00381       virtual void fill(typename DetSetVector<T>::FastFiller&) = 0;
00382     };
00383   }
00384   
00385     
00386 
00387   template<typename T>
00388   inline DetSetVector<T>::DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter, 
00389                                        const std::vector<det_id_type>& iDets,
00390                                        int isubdet):  
00391     m_subdetId(isubdet) {
00392     getter=iGetter;
00393 
00394     m_ids.reserve(iDets.size());
00395     det_id_type sanityCheck = 0;
00396     for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
00397         itDetId != itDetIdEnd;
00398         ++itDetId) {
00399       assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
00400       sanityCheck = *itDetId;
00401       m_ids.push_back(*itDetId);
00402     }
00403   }
00404 
00405   template<typename T>
00406   inline void DetSetVector<T>::updateImpl(Item & item)  {
00407     // no getter or already updated
00408     if (getter.empty() || item.offset!=-1) return;
00409     item.offset = int(m_data.size());
00410     FastFiller ff(*this,item);
00411     (*boost::any_cast<boost::shared_ptr<Getter> >(&getter))->fill(ff);
00412   }
00413 
00414 
00415   template<typename T>
00416   inline DetSet<T>::DetSet(DetSetVector<T> const & icont,
00417                            typename DetSetVector<T>::Item const & item ) :
00418     m_id(0), m_data(0), m_size(0){
00419     icont.update(item);
00420     set(icont,item);
00421   }
00422   
00423   
00424   template<typename T>
00425   inline void DetSet<T>::set(DetSetVector<T> const & icont,
00426                              typename Container::Item const & item) {
00427     icont.update(item);
00428     m_id=item.id; 
00429     m_data=&icont.data()[item.offset]; 
00430     m_size=item.size;
00431   }
00432   
00433 }
00434 
00435 #include "DataFormats/Common/interface/Ref.h"
00436 #include <boost/mpl/assert.hpp>
00437 #include <boost/type_traits/is_same.hpp>
00438 
00439 //specialize behavior of edm::Ref to get access to the 'Det'
00440 namespace edm {
00441     /* Reference to an item inside a new DetSetVector ... */
00442     namespace refhelper {
00443         template<typename T>
00444             struct FindTrait<typename edmNew::DetSetVector<T>,T> {
00445                 typedef typename edmNew::DetSetVector<T>::FindForDetSetVector value;
00446             };
00447     }
00448     /* ... as there was one for the original DetSetVector*/
00449 
00450     /* Probably this one is not that useful .... */
00451     namespace refhelper {
00452         template<typename T>
00453             struct FindSetForNewDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, edmNew::DetSet<T> > {
00454                 typedef FindSetForNewDetSetVector<T> self;
00455                 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00456                     return &(iContainer[iIndex]);
00457                 }
00458             };
00459 
00460         template<typename T>
00461             struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T> > {
00462                 typedef FindSetForNewDetSetVector<T> value;
00463             };
00464     }
00465     /* ... implementation is provided, just in case it's needed */
00466 }
00467 
00468 namespace edmNew {
00469    //helper function to make it easier to create a edm::Ref to a new DSV
00470   template<class HandleT>
00471   edm::Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00472   makeRefTo(const HandleT& iHandle,
00473              typename HandleT::element_type::value_type::const_iterator itIter) {
00474     BOOST_MPL_ASSERT((boost::is_same<typename HandleT::element_type, DetSetVector<typename HandleT::element_type::value_type::value_type> >));
00475     typename HandleT::element_type::size_type index = (itIter - &*iHandle->data().begin()); 
00476     return edm::Ref<typename HandleT::element_type,
00477                typename HandleT::element_type::value_type::value_type>
00478               (iHandle,index);
00479   }
00480 }
00481 
00482 
00483 #endif
00484