88// granted to it by virtue of its status as an Intergovernmental Organization
99// or submit itself to any jurisdiction.
1010
11- // / \file MCTruthContainer.h
12- // / \brief Definition of a container to keep Monte Carlo truth external to simulation objects
13- // / \author Sandro Wenzel - June 2017
11+ // / \brief Definition of a container to keep/associate and arbitrary
12+ // / number of labels associated to an index with contiguous or non-contiguous label storage
13+ // \author Sandro Wenzel - June 2017
1414
1515#ifndef ALICEO2_DATAFORMATS_LABELCONTAINER_H_
1616#define ALICEO2_DATAFORMATS_LABELCONTAINER_H_
2121#include < type_traits>
2222#include < iterator>
2323#include < gsl/gsl> // for guideline support library; array_view
24- #include < iostream>
2524
2625namespace o2
2726{
2827namespace dataformats
2928{
30-
29+
30+ // a label container with both contiguous and non-contiguous modes
31+ // for label storage
32+ // NOTE: the current specialization for contiguous storage is not
33+ // yet on par with MCTruthContainer ... but eventually we might unify
34+ // everything and keep only the more generic and configurable version
3135template <typename LabelType, bool isContiguousStorage = true >
32- class LabelContainer : public TNamed
36+ class LabelContainer
3337{
3438 public:
3539 struct HeaderElementContinuous {
3640 HeaderElementContinuous () = default ; // for ROOT IO
3741 HeaderElementContinuous (ushort s, uint i) : size(s), index(i) {}
38- uint index = 0 ; // index of first label in the actual label storage
42+ uint index = 0 ; // index of first label in the actual label storage
3943 ushort size = 0 ; // total number of labels
4044 ClassDefNV (HeaderElementContinuous, 1 );
4145 };
4246
4347 struct HeaderElementLinked {
4448 HeaderElementLinked () = default ; // for ROOT IO
4549 HeaderElementLinked (uint i, int l, ushort s) : index(i), lastindex(l), size(s) {}
46- uint index = 0 ; // index of first label in the actual label storage
50+ uint index = 0 ; // index of first label in the actual label storage
4751 uint lastindex = 0 ; // index of last label in the actual label storage
48- ushort size = 0 ; // total number of labels
52+ ushort size = 0 ; // total number of labels
4953 ClassDefNV (HeaderElementLinked, 1 );
5054 };
5155
5256 using HeaderElement = typename std::conditional<isContiguousStorage, HeaderElementContinuous, HeaderElementLinked>::type;
5357 using StoredLabelType = typename std::conditional<isContiguousStorage, LabelType, std::pair<LabelType, int >>::type;
5458
5559 // internal functions allowing the iterator implementation to be completely generic
56- static uint getNextIndex (uint index, std::vector<LabelType> const &/* labels*/ ) {
57- return index+1 ;
60+ static uint getNextIndex (uint index, std::vector<LabelType> const & /* labels*/ )
61+ {
62+ return index + 1 ;
5863 }
59- static uint getNextIndex (uint index, std::vector<std::pair<LabelType, int >> const &labels) {
64+ static uint getNextIndex (uint index, std::vector<std::pair<LabelType, int >> const & labels)
65+ {
6066 return labels[index].second ;
6167 }
62- static LabelType& dereference (std::vector<LabelType> &v, int index) {
68+ static LabelType& dereference (std::vector<LabelType>& v, int index)
69+ {
6370 return v[index];
6471 }
65- static LabelType& dereference (std::vector<std::pair<LabelType,int >> &v, int index) {
72+ static LabelType& dereference (std::vector<std::pair<LabelType, int >>& v, int index)
73+ {
6674 return v[index].first ;
6775 }
68- static int lastIndex (HeaderElementContinuous const &h) {
76+ static int lastIndex (HeaderElementContinuous const & h)
77+ {
6978 return h.index + h.size ;
7079 }
71- static int lastIndex (HeaderElementLinked const &h) {
80+ static int lastIndex (HeaderElementLinked const & h)
81+ {
7282 // -1 since this is indication of end of linked list
7383 return -1 ;
7484 }
75-
76- // an iterator class to iterate over truthelements
85+
86+ // an iterator class to iterate over truthelements
7787 class Iterator : public std ::iterator<std::input_iterator_tag, LabelType>
7888 {
79- private:
80- std::vector<StoredLabelType> &mLabelsRef ; // reference to labels vector
81- int index; // startindex
82- public:
83- Iterator (std::vector<StoredLabelType> &v, int i) : mLabelsRef (v), index(i) {}
84- Iterator (const Iterator& it) : mLabelsRef (it.mLabelsRef ), index(it.index) {}
85- Iterator& operator =(const Iterator& it) {
86- mLabelsRef = it.mLabelsRef ;
87- index = it.index ;
88- return *this ;
89- }
90-
91- // go to the next element as indicated by second entry of StoredLabelType
92- Iterator& operator ++() {index=getNextIndex (index, mLabelsRef );return *this ;}
89+ private:
90+ std::vector<StoredLabelType>& mLabelsRef ; // reference to labels vector
91+ int index; // startindex
92+ public:
93+ Iterator (std::vector<StoredLabelType>& v, int i) : mLabelsRef (v), index(i) {}
94+ Iterator (const Iterator& it) : mLabelsRef (it.mLabelsRef ), index(it.index) {}
95+ Iterator& operator =(const Iterator& it)
96+ {
97+ mLabelsRef = it.mLabelsRef ;
98+ index = it.index ;
99+ return *this ;
100+ }
101+
102+ // go to the next element as indicated by second entry of StoredLabelType
103+ Iterator& operator ++()
104+ {
105+ index = getNextIndex (index, mLabelsRef );
106+ return *this ;
107+ }
93108
94- bool operator ==(const Iterator& rhs) const {return index== rhs.index ;}
95- bool operator !=(const Iterator& rhs) const {return index!= rhs.index ;}
96- LabelType& operator *() {return dereference (mLabelsRef , index);}
109+ bool operator ==(const Iterator& rhs) const { return index == rhs.index ; }
110+ bool operator !=(const Iterator& rhs) const { return index != rhs.index ; }
111+ LabelType& operator *() { return dereference (mLabelsRef , index); }
97112 };
98113
99114 // a proxy class offering a (non-owning) container view on labels of a given data index
100115 // container offers basic forward iterator functionality
101- class LabelView {
116+ class LabelView
117+ {
102118 private:
103119 int dataindex;
104120 std::vector<HeaderElement>& mHeaderArrayRef ;
105121 std::vector<StoredLabelType>& mLabelArrayRef ;
106-
122+
107123 public:
108- constexpr LabelView (int i, std::vector<HeaderElement> & v1, std::vector<StoredLabelType> & v2) : dataindex(i), mHeaderArrayRef(v1), mLabelArrayRef(v2) {}
109-
124+ constexpr LabelView (int i, std::vector<HeaderElement>& v1, std::vector<StoredLabelType>& v2) : dataindex(i), mHeaderArrayRef(v1), mLabelArrayRef(v2) {}
125+
110126 // begin + end iterators to loop over the labels
111- Iterator begin () {return dataindex < mHeaderArrayRef .size () ?
112- Iterator (mLabelArrayRef , mHeaderArrayRef [dataindex].index ) : Iterator (mLabelArrayRef , 0 );
127+ Iterator begin ()
128+ {
129+ return dataindex < mHeaderArrayRef .size () ? Iterator (mLabelArrayRef , mHeaderArrayRef [dataindex].index ) : Iterator (mLabelArrayRef , 0 );
113130 }
114131
115- Iterator end () {return dataindex < mHeaderArrayRef .size () ?
116- Iterator (mLabelArrayRef , lastIndex (mHeaderArrayRef [dataindex])) : Iterator (mLabelArrayRef , 0 );
132+ Iterator end ()
133+ {
134+ return dataindex < mHeaderArrayRef .size () ? Iterator (mLabelArrayRef , lastIndex (mHeaderArrayRef [dataindex])) : Iterator (mLabelArrayRef , 0 );
117135 }
118136
119137 // get number of labels
120- size_t size () const {return dataindex < mHeaderArrayRef .size () ? mHeaderArrayRef [dataindex].size : 0 ;}
138+ size_t size () const { return dataindex < mHeaderArrayRef .size () ? mHeaderArrayRef [dataindex].size : 0 ; }
121139 };
122140
123- static void addLabelImpl (int dataindex, std::vector<HeaderElementContinuous> &headerv, std::vector<LabelType> &labelv, LabelType const &label) {
141+ static void addLabelImpl (int dataindex, std::vector<HeaderElementContinuous>& headerv, std::vector<LabelType>& labelv, LabelType const & label)
142+ {
124143 if (dataindex < headerv.size ()) {
125144 // look if we have something for this dataindex already
126145 // must currently be the last one
@@ -137,24 +156,24 @@ class LabelContainer : public TNamed
137156 labelv.emplace_back (label);
138157 }
139158
140- static void addLabelImpl (int dataindex, std::vector<HeaderElementLinked> &headerv, std::vector<std::pair<LabelType,int >> &labelv, LabelType const &label) {
141- labelv.emplace_back (std::make_pair (label,-1 ));
159+ static void addLabelImpl (int dataindex, std::vector<HeaderElementLinked>& headerv, std::vector<std::pair<LabelType, int >>& labelv, LabelType const & label)
160+ {
161+ labelv.emplace_back (std::make_pair (label, -1 ));
142162 // something exists for this dataindex already
143163 if (dataindex < headerv.size ()) {
144164 auto & header = headerv[dataindex];
145165 // increase size
146166 header.size ++;
147- const auto lastindex = labelv.size ();
167+ const auto lastindex = labelv.size () - 1 ;
148168 // fix link at previous last index
149169 labelv[header.lastindex ].second = lastindex;
150170 // new last index
151171 header.lastindex = lastindex;
152- }
153- else {
172+ } else {
154173 // we support only appending in order?
155174 assert (dataindex == headerv.size ());
156175 // add a new header element; pointing to last slot in mTruthArray
157- const auto lastpos = labelv.size ()- 1 ;
176+ const auto lastpos = labelv.size () - 1 ;
158177 headerv.emplace_back (lastpos, lastpos, 1 );
159178 }
160179 }
@@ -166,7 +185,15 @@ class LabelContainer : public TNamed
166185 public:
167186 // constructor
168187 LabelContainer () = default ;
169- ~LabelContainer () final = default ;
188+ ~LabelContainer () = default ;
189+
190+ // reserve some initial space in the actual storage
191+ // (to hold at least n labels)
192+ void reserve (int n)
193+ {
194+ mHeaderArray .reserve (n);
195+ mLabelArray .reserve (n);
196+ }
170197
171198 void clear ()
172199 {
@@ -175,29 +202,29 @@ class LabelContainer : public TNamed
175202 }
176203
177204 // / add a label for a dataindex
178- void addLabel (uint dataindex, LabelType const & label) {
179- // refer to concrete specialized implementation
180- addLabelImpl (dataindex, mHeaderArray , mLabelArray , label);
181- }
205+ void addLabel (uint dataindex, LabelType const & label)
206+ {
207+ // refer to concrete specialized implementation
208+ addLabelImpl (dataindex, mHeaderArray , mLabelArray , label);
209+ }
182210
183211 // / get a container view on labels allowing use standard forward iteration in user code
184- LabelView getLabels (int dataindex) {return LabelView (dataindex, mHeaderArray , mLabelArray );}
212+ LabelView getLabels (int dataindex) { return LabelView (dataindex, mHeaderArray , mLabelArray ); }
185213
186214 // / fill an external vector container with labels
187215 // / might be useful to perform additional operations such as sorting on the labels;
188216 // / the external vector can be reused to avoid allocations/deallocs)
189- void fillVectorOfLabels (int dataindex, std::vector<LabelType> &v) {
217+ void fillVectorOfLabels (int dataindex, std::vector<LabelType>& v)
218+ {
190219 // / fixme: provide a template specialized fast version for contiguous storage
191220 v.clear ();
192- for (auto & e : getLabels (dataindex)) {
221+ for (auto & e : getLabels (dataindex)) {
193222 v.push_back (e);
194223 }
195224 }
196-
197- // ClassDefOverride(LabelContainer, 1);
198225}; // end class
199226
200- }
201- }
227+ } // namespace dataformats
228+ } // namespace o2
202229
203230#endif
0 commit comments