CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DetSetVectorNew.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_DetSetVectorNew_h
2 #define DataFormats_Common_DetSetVectorNew_h
3 
5 // #include "DataFormats/Common/interface/DetSet.h" // to get det_id_type
8 
9 #include <boost/iterator_adaptors.hpp>
10 #include <boost/iterator/transform_iterator.hpp>
11 #include <boost/iterator/counting_iterator.hpp>
12 #include <boost/any.hpp>
13 #include "boost/shared_ptr.hpp"
15 
16 
17 #include<vector>
18 #include <cassert>
19 
20 namespace edm { namespace refhelper { template<typename T> struct FindForNewDetSetVector; } }
21 
22 //FIXME remove New when ready
23 namespace edmNew {
24  typedef uint32_t det_id_type;
25 
26  namespace dslv {
27  template< typename T> class LazyGetter;
28  }
29 
30  /* transient component of DetSetVector
31  * for pure conviniency of dictioanary declaration
32  */
33  namespace dstvdetails {
36  bool filling;
38 
39  typedef unsigned int size_type; // for persistency
40  typedef unsigned int id_type;
41 
42  struct Item {
43  Item(id_type i=0, int io=-1, size_type is=0) : id(i), offset(io), size(is){}
45  int offset;
47  bool operator<(Item const &rh) const { return id<rh.id;}
48  operator id_type() const { return id;}
49  };
50 
51  };
52  void errorFilling();
53  void errorIdExists(det_id_type iid);
54  void throw_range(det_id_type iid);
55  }
56 
67  template<typename T>
68  class DetSetVector : private dstvdetails::DetSetVectorTrans {
69  public:
71  typedef Trans::Item Item;
72  typedef unsigned int size_type; // for persistency
73  typedef unsigned int id_type;
74  typedef T data_type;
78  // FIXME not sure make sense....
79  typedef DetSet value_type;
80  typedef id_type key_type;
81 
82 
83  typedef std::vector<Item> IdContainer;
84  typedef std::vector<data_type> DataContainer;
85  typedef typename IdContainer::iterator IdIter;
86  typedef typename std::vector<data_type>::iterator DataIter;
87  typedef std::pair<IdIter,DataIter> IterPair;
88  typedef typename IdContainer::const_iterator const_IdIter;
89  typedef typename std::vector<data_type>::const_iterator const_DataIter;
90  typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
91 
93 
94  struct IterHelp {
96  IterHelp() : v(0){}
97  IterHelp(DetSetVector<T> const & iv) : v(&iv){}
98 
99  result_type & operator()(Item const& item) const {
100  detset.set(*v,item);
101  return detset;
102  }
103  private:
106  };
107 
108  typedef boost::transform_iterator<IterHelp,const_IdIter> const_iterator;
109  typedef std::pair<const_iterator,const_iterator> Range;
110 
111  /* fill the lastest inserted DetSet
112  */
113  class FastFiller {
114  public:
119 
120  FastFiller(DetSetVector<T> & iv, id_type id, bool isaveEmpty=false) :
121  v(iv), item(v.push_back(id)), saveEmpty(isaveEmpty) {
122  if (v.filling) dstvdetails::errorFilling();
123  v.filling=true;
124  }
125  FastFiller(DetSetVector<T> & iv, typename DetSetVector<T>::Item & it, bool isaveEmpty=false) :
126  v(iv), item(it), saveEmpty(isaveEmpty) {
127  if (v.filling) dstvdetails::errorFilling();
128  v.filling=true;
129  }
131  if (!saveEmpty && item.size==0) {
132  v.pop_back(item.id);
133  }
134  v.filling=false;
135  }
136 
137  void abort() {
138  v.pop_back(item.id);
139  saveEmpty=true; // avoid mess in destructor
140  }
141 
143  v.m_data.reserve(item.offset+s);
144  }
145 
147  v.m_data.resize(item.offset+s);
148  item.size=s;
149  }
150 
151  id_type id() const { return item.id;}
152  size_type size() const { return item.size;}
153  bool empty() const { return item.size==0;}
154 
156  return v.m_data[item.offset+i];
157  }
158  DataIter begin() { return v.m_data.begin()+ item.offset;}
159  DataIter end() { return v.m_data.end();}
160 
161  void push_back(data_type const & d) {
162  v.m_data.push_back(d);
163  item.size++;
164  }
165 #ifndef CMS_NOCXX11
166  void push_back(data_type && d) {
167  v.m_data.push_back(std::move(d));
168  item.size++;
169  }
170 
171 #endif
172 
173  data_type & back() { return v.m_data.back();}
174 
175  private:
178  bool saveEmpty;
179  };
180  friend class FastFiller;
181 
182  class FindForDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
183  public:
184  typedef FindForDetSetVector self;
185  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
186  return &(iContainer.m_data[iIndex]);
187  }
188  };
189  friend class FindForDetSetVector;
190 
191  explicit DetSetVector(int isubdet=0) :
192  m_subdetId(isubdet) {}
193 
194  DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter, const std::vector<det_id_type>& iDets,
195  int isubdet=0);
196 
197 
199  // delete content if T is pointer...
200  }
201 
202  void swap(DetSetVector & rh) {
203  std::swap(m_subdetId,rh.m_subdetId);
204  std::swap(m_ids,rh.m_ids);
205  std::swap(m_data,rh.m_data);
206  }
207 
208  void swap(IdContainer & iic, DataContainer & idc) {
209  std::swap(m_ids,iic);
210  std::swap(m_data,idc);
211  }
212 
213  void reserve(size_t isize, size_t dsize) {
214  m_ids.reserve(isize);
215  m_data.reserve(dsize);
216  }
217 
218  void resize(size_t isize, size_t dsize) {
219  m_ids.resize(isize);
220  m_data.resize(dsize);
221  }
222 
223  // FIXME not sure what the best way to add one cell to cont
224  DetSet insert(id_type iid, data_type const * idata, size_type isize) {
225  Item & item = addItem(iid,isize);
226  m_data.resize(m_data.size()+isize);
227  std::copy(idata,idata+isize,m_data.begin()+item.offset);
228  return DetSet(*this,item);
229  }
230  //make space for it
232  Item & item = addItem(iid,isize);
233  m_data.resize(m_data.size()+isize);
234  return DetSet(*this,item);
235  }
236 
237  // to be used with a FastFiller
239  return addItem(iid,0);
240  }
241 
242  // remove last entry (usually only if empty...)
243  void pop_back(id_type iid) {
244  const_IdIter p = findItem(iid);
245  if (p==m_ids.end()) return; //bha!
246  // sanity checks... (shall we throw or assert?)
247  if ((*p).size>0&& (*p).offset>-1 &&
248  m_data.size()==(*p).offset+(*p).size)
249  m_data.resize((*p).offset);
250  m_ids.erase( m_ids.begin()+(p-m_ids.begin()));
251  }
252 
253  private:
254 
255  Item & addItem(id_type iid, size_type isize) {
256  Item it(iid,size_type(m_data.size()),isize);
257  IdIter p = std::lower_bound(m_ids.begin(),
258  m_ids.end(),
259  it);
260  if (p!=m_ids.end() && !(it<*p)) dstvdetails::errorIdExists(iid);
261  return *m_ids.insert(p,it);
262  }
263 
264 
265 
266  public:
267 
268 
269  //---------------------------------------------------------
270 
271  bool exists(id_type i) const {
272  return findItem(i)!=m_ids.end();
273  }
274 
275  bool isValid(id_type i) const {
276  const_IdIter p = findItem(i);
277  return p!=m_ids.end() && (*p).offset!=-1;
278  }
279 
280  /*
281  DetSet operator[](id_type i) {
282  const_IdIter p = findItem(i);
283  if (p==m_ids.end()) what???
284  return DetSet(*this,p-m_ids.begin());
285  }
286  */
287 
288 
290  const_IdIter p = findItem(i);
291  if (p==m_ids.end()) dstvdetails::throw_range(i);
292  return DetSet(*this,*p);
293  }
294 
295  // slow interface
297  const_IdIter p = findItem(i);
298  return (p==m_ids.end()) ? end() :
299  boost::make_transform_iterator(p,
300  IterHelp(*this));
301  }
302 
303  // slow interface
305  std::pair<const_IdIter,const_IdIter> p =
306  std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
307  return (p.first!=p.second) ? p.first : m_ids.end();
308  }
309 
311  return boost::make_transform_iterator(m_ids.begin(),
312  IterHelp(*this));
313  }
314 
315  const_iterator end() const {
316  return boost::make_transform_iterator(m_ids.end(),
317  IterHelp(*this));
318  }
319 
320 
321  // return an iterator range (implemented here to avoid dereference of detset)
322  template<typename CMP>
323  Range equal_range(id_type i, CMP cmp) const {
324  std::pair<const_IdIter,const_IdIter> p =
325  std::equal_range(m_ids.begin(),m_ids.end(),i,cmp);
326  return Range(boost::make_transform_iterator(p.first,IterHelp(*this)),
327  boost::make_transform_iterator(p.second,IterHelp(*this))
328  );
329  }
330 
331  int subdetId() const { return m_subdetId; }
332 
333  bool empty() const { return m_ids.empty();}
334 
335 
336  size_type dataSize() const { return m_data.size(); }
337 
338  size_type size() const { return m_ids.size();}
339 
340  //FIXME fast interfaces, not consistent with associative nature of container....
341 
342  data_type operator()(size_t cell, size_t frame) const {
343  return m_data[m_ids[cell].offset+frame];
344  }
345 
346  data_type const * data(size_t cell) const {
347  return &m_data[m_ids[cell].offset];
348  }
349 
350  size_type detsetSize(size_t cell) const { return m_ids[cell].size; }
351 
352  id_type id(size_t cell) const {
353  return m_ids[cell].id;
354  }
355 
356  Item const & item(size_t cell) const {
357  return m_ids[cell];
358  }
359 
360  //------------------------------
361 
362  // IdContainer const & ids() const { return m_ids;}
363  DataContainer const & data() const { return m_data;}
364 
365 
366  void update(Item const & item) const {
367  const_cast<self*>(this)->updateImpl(const_cast<Item&>(item));
368  }
369 
370  //Used by ROOT storage
372 
373  private:
374 
375  void updateImpl(Item & item);
376 
377  private:
378  // subdetector id (as returned by DetId::subdetId())
380 
381 
384 
385  };
386 
387  namespace dslv {
388  template< typename T>
389  class LazyGetter {
390  public:
391  virtual ~LazyGetter() {}
392  virtual void fill(typename DetSetVector<T>::FastFiller&) = 0;
393  };
394  }
395 
396 
397 
398  template<typename T>
399  inline DetSetVector<T>::DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter,
400  const std::vector<det_id_type>& iDets,
401  int isubdet):
402  m_subdetId(isubdet) {
403  getter=iGetter;
404 
405  m_ids.reserve(iDets.size());
406  det_id_type sanityCheck = 0;
407  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
408  itDetId != itDetIdEnd;
409  ++itDetId) {
410  assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
411  sanityCheck = *itDetId;
412  m_ids.push_back(*itDetId);
413  }
414  }
415 
416  template<typename T>
417  inline void DetSetVector<T>::updateImpl(Item & item) {
418  // no getter or already updated
419  if (getter.empty() || item.offset!=-1) return;
420  item.offset = int(m_data.size());
421  FastFiller ff(*this,item);
422  (*boost::any_cast<boost::shared_ptr<Getter> >(&getter))->fill(ff);
423  }
424 
425 
426  template<typename T>
427  inline DetSet<T>::DetSet(DetSetVector<T> const & icont,
428  typename DetSetVector<T>::Item const & item ) :
429  m_id(0), m_data(0), m_size(0){
430  icont.update(item);
431  set(icont,item);
432  }
433 
434 
435  template<typename T>
436  inline void DetSet<T>::set(DetSetVector<T> const & icont,
437  typename Container::Item const & item) {
438  icont.update(item);
439  m_id=item.id;
440  m_data=&icont.data()[item.offset];
441  m_size=item.size;
442  }
443 
444 }
445 
447 #include <boost/mpl/assert.hpp>
448 #include <boost/type_traits/is_same.hpp>
449 
450 //specialize behavior of edm::Ref to get access to the 'Det'
451 namespace edm {
452  /* Reference to an item inside a new DetSetVector ... */
453  namespace refhelper {
454  template<typename T>
455  struct FindTrait<typename edmNew::DetSetVector<T>,T> {
457  };
458  }
459  /* ... as there was one for the original DetSetVector*/
460 
461  /* Probably this one is not that useful .... */
462  namespace refhelper {
463  template<typename T>
464  struct FindSetForNewDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, edmNew::DetSet<T> > {
466  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
467  return &(iContainer[iIndex]);
468  }
469  };
470 
471  template<typename T>
472  struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T> > {
474  };
475  }
476  /* ... implementation is provided, just in case it's needed */
477 }
478 
479 namespace edmNew {
480  //helper function to make it easier to create a edm::Ref to a new DSV
481  template<class HandleT>
483  makeRefTo(const HandleT& iHandle,
484  typename HandleT::element_type::value_type::const_iterator itIter) {
485  BOOST_MPL_ASSERT((boost::is_same<typename HandleT::element_type, DetSetVector<typename HandleT::element_type::value_type::value_type> >));
486  typename HandleT::element_type::size_type index = (itIter - &*iHandle->data().begin());
487  return edm::Ref<typename HandleT::element_type,
489  (iHandle,index);
490  }
491 }
492 
494 
495 namespace edm {
496  template<typename T>
497  class ContainerMaskTraits<edmNew::DetSetVector<T> > {
498  public:
499  typedef T value_type;
500 
501  static size_t size(const edmNew::DetSetVector<T>* iContainer) { return iContainer->dataSize();}
502  static unsigned int indexFor(const value_type* iElement, const edmNew::DetSetVector<T>* iContainer) {
503  return iElement-&(iContainer->data().front());
504  }
505  };
506 }
507 
508 #endif
509 
bool isValid(id_type i) const
DataContainer const & data() const
edm::Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type > makeRefTo(const HandleT &iHandle, typename HandleT::element_type::value_type::const_iterator itIter)
static unsigned int indexFor(const value_type *iElement, const edmNew::DetSetVector< T > *iContainer)
int i
Definition: DBlmapReader.cc:9
void push_back(data_type const &d)
void update(Item const &item) const
boost::transform_iterator< IterHelp, const_IdIter > const_iterator
const_iterator begin() const
size_type dataSize() const
string fill
Definition: lumiContext.py:319
DetSetVector< T >::id_type id_type
std::vector< data_type > DataContainer
Item & push_back(id_type iid)
Range equal_range(id_type i, CMP cmp) const
const_IdIter findItem(id_type i) const
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:34
IdContainer::iterator IdIter
unsigned int det_id_type
Definition: DetSetNew.h:8
edmNew::DetSetVector< T >::FindForDetSetVector value
std::vector< data_type >::const_iterator const_DataIter
void swap(DetSetVector &rh)
void throw_range(det_id_type iid)
list namespace
Definition: asciidump.py:379
std::pair< const_IdIter, const_DataIter > const_IterPair
DetSetVector(int isubdet=0)
std::pair< const_iterator, const_iterator > Range
void pop_back(id_type iid)
#define CMS_CLASS_VERSION(_version_)
const_iterator find(id_type i) const
id_type id(size_t cell) const
uint16_t size_type
dstvdetails::DetSetVectorTrans Trans
self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex)
Item const & item(size_t cell) const
DetSetVector< T > const * v
Item & addItem(id_type iid, size_type isize)
DetSetVector< T >::data_type value_type
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
void set(Container const &icont, typename Container::Item const &item)
bool exists(id_type i) const
data_type const * data(size_t cell) const
FastFiller(DetSetVector< T > &iv, id_type id, bool isaveEmpty=false)
Item(id_type i=0, int io=-1, size_type is=0)
DetSetVector< T >::Item & item
void swap(IdContainer &iic, DataContainer &idc)
const_iterator end() const
Container::value_type value_type
DetSetVector< T >::id_type key_type
static size_t size(const edmNew::DetSetVector< T > *iContainer)
void resize(size_t isize, size_t dsize)
size_type detsetSize(size_t cell) const
DetSet insert(id_type iid, data_type const *idata, size_type isize)
std::vector< Item > IdContainer
friend class FindForDetSetVector
dslv::LazyGetter< T > Getter
void errorIdExists(det_id_type iid)
void reserve(size_t isize, size_t dsize)
std::vector< data_type >::iterator DataIter
result_type & operator()(Item const &item) const
#define private
Definition: FWFileEntry.h:17
DetSet insert(id_type iid, size_type isize)
size_type size() const
std::pair< IdIter, DataIter > IterPair
void updateImpl(Item &item)
IdContainer::const_iterator const_IdIter
data_type operator()(size_t cell, size_t frame) const
self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex)
edmNew::DetSet< T > DetSet
volatile std::atomic< bool > shutdown_flag false
FastFiller(DetSetVector< T > &iv, typename DetSetVector< T >::Item &it, bool isaveEmpty=false)
data_type & operator[](size_type i)
edm::refhelper::FindForNewDetSetVector< data_type > RefFinder
long double T
DetSetVector< T >::size_type size_type
DetSet operator[](id_type i) const
IterHelp(DetSetVector< T > const &iv)
unsigned int size_type