Project
Loading...
Searching...
No Matches
LabelContainer.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14// \author Sandro Wenzel - June 2017
15
16#ifndef ALICEO2_DATAFORMATS_LABELCONTAINER_H_
17#define ALICEO2_DATAFORMATS_LABELCONTAINER_H_
18
19#include <TNamed.h>
20#include <cassert>
21#include <stdexcept>
22#include <type_traits>
23#include <iterator>
24#include <gsl/gsl> // for guideline support library; array_view
25
26namespace o2::dataformats
27{
28
29// a label container with both contiguous and non-contiguous modes
30// for label storage
31// NOTE: the current specialization for contiguous storage is not
32// yet on par with MCTruthContainer ... but eventually we might unify
33// everything and keep only the more generic and configurable version
34template <typename LabelType, bool isContiguousStorage = true>
36{
37 public:
39 HeaderElementContinuous() = default; // for ROOT IO
40 HeaderElementContinuous(unsigned short s, unsigned int i) : size(s), index(i) {}
41 unsigned int index = 0; // index of first label in the actual label storage
42 unsigned short size = 0; // total number of labels
44 };
45
47 HeaderElementLinked() = default; // for ROOT IO
48 HeaderElementLinked(unsigned int i, int l, unsigned short s) : index(i), lastindex(l), size(s) {}
49 unsigned int index = 0; // index of first label in the actual label storage
50 unsigned int lastindex = 0; // index of last label in the actual label storage
51 unsigned short size = 0; // total number of labels
53 };
54
55 using HeaderElement = typename std::conditional<isContiguousStorage, HeaderElementContinuous, HeaderElementLinked>::type;
56 using StoredLabelType = typename std::conditional<isContiguousStorage, LabelType, std::pair<LabelType, int>>::type;
57
58 // internal functions allowing the iterator implementation to be completely generic
59 static unsigned int getNextIndex(unsigned int index, std::vector<LabelType> const& /*labels*/)
60 {
61 return index + 1;
62 }
63 static unsigned int getNextIndex(unsigned int index, std::vector<std::pair<LabelType, int>> const& labels)
64 {
65 return labels[index].second;
66 }
67 static LabelType& dereference(std::vector<LabelType>& v, int index)
68 {
69 return v[index];
70 }
71 static LabelType& dereference(std::vector<std::pair<LabelType, int>>& v, int index)
72 {
73 return v[index].first;
74 }
76 {
77 return h.index + h.size;
78 }
79 static int lastIndex(HeaderElementLinked const& h)
80 {
81 // -1 since this is indication of end of linked list
82 return -1;
83 }
84
85 // an iterator class to iterate over truthelements
87 {
88 private:
89 using iterator_category = std::input_iterator_tag;
90 using value_type = LabelType;
91 using difference_type = std::ptrdiff_t;
92 using pointer = LabelType*;
93 using reference = LabelType&;
94 std::vector<StoredLabelType>& mLabelsRef; // reference to labels vector
95 int index; // startindex
96 public:
97 Iterator(std::vector<StoredLabelType>& v, int i) : mLabelsRef(v), index(i) {}
98 Iterator(const Iterator& it) : mLabelsRef(it.mLabelsRef), index(it.index) {}
100 {
101 mLabelsRef = it.mLabelsRef;
102 index = it.index;
103 return *this;
104 }
105
106 // go to the next element as indicated by second entry of StoredLabelType
108 {
109 index = getNextIndex(index, mLabelsRef);
110 return *this;
111 }
112
113 bool operator==(const Iterator& rhs) const { return index == rhs.index; }
114 bool operator!=(const Iterator& rhs) const { return index != rhs.index; }
115 LabelType& operator*() { return dereference(mLabelsRef, index); }
116 };
117
118 // a proxy class offering a (non-owning) container view on labels of a given data index
119 // container offers basic forward iterator functionality
121 {
122 private:
123 int dataindex;
124 std::vector<HeaderElement>& mHeaderArrayRef;
125 std::vector<StoredLabelType>& mLabelArrayRef;
126
127 public:
128 constexpr LabelView(int i, std::vector<HeaderElement>& v1, std::vector<StoredLabelType>& v2) : dataindex(i), mHeaderArrayRef(v1), mLabelArrayRef(v2) {}
129
130 // begin + end iterators to loop over the labels
132 {
133 return dataindex < mHeaderArrayRef.size() ? Iterator(mLabelArrayRef, mHeaderArrayRef[dataindex].index) : Iterator(mLabelArrayRef, 0);
134 }
135
137 {
138 return dataindex < mHeaderArrayRef.size() ? Iterator(mLabelArrayRef, lastIndex(mHeaderArrayRef[dataindex])) : Iterator(mLabelArrayRef, 0);
139 }
140
141 // get number of labels
142 size_t size() const { return dataindex < mHeaderArrayRef.size() ? mHeaderArrayRef[dataindex].size : 0; }
143 };
144
145 static void addLabelImpl(int dataindex, std::vector<HeaderElementContinuous>& headerv, std::vector<LabelType>& labelv, LabelType const& label)
146 {
147 if (dataindex < headerv.size()) {
148 // look if we have something for this dataindex already
149 // must currently be the last one
150 if (dataindex != (headerv.size() - 1)) {
151 throw std::runtime_error("LabelContainer: unsupported code path");
152 }
153 } else {
154 assert(dataindex == headerv.size());
155 // add a new one
156 headerv.emplace_back(0, labelv.size());
157 }
158 auto& header = headerv[dataindex];
159 header.size++;
160 labelv.emplace_back(label);
161 }
162
163 static void addLabelImpl(int dataindex, std::vector<HeaderElementLinked>& headerv, std::vector<std::pair<LabelType, int>>& labelv, LabelType const& label)
164 {
165 labelv.emplace_back(std::make_pair(label, -1));
166 // something exists for this dataindex already
167 if (dataindex < headerv.size()) {
168 auto& header = headerv[dataindex];
169 // increase size
170 header.size++;
171 const auto lastindex = labelv.size() - 1;
172 // fix link at previous last index
173 labelv[header.lastindex].second = lastindex;
174 // new last index
175 header.lastindex = lastindex;
176 } else {
177 // we support only appending in order?
178 assert(dataindex == headerv.size());
179 // add a new header element; pointing to last slot in mTruthArray
180 const auto lastpos = labelv.size() - 1;
181 headerv.emplace_back(lastpos, lastpos, 1);
182 }
183 }
184
185 // declaring the data members
186 std::vector<HeaderElement> mHeaderArray; // the header structure array serves as an index into the actual storage
187 std::vector<StoredLabelType> mLabelArray; // the buffer containing the actual truth information
188
189 public:
190 // constructor
191 LabelContainer() = default;
192 ~LabelContainer() = default;
193
194 // reserve some initial space in the actual storage
195 // (to hold at least n labels)
196 void reserve(int n)
197 {
198 mHeaderArray.reserve(n);
199 mLabelArray.reserve(n);
200 }
201
202 void clear()
203 {
204 mHeaderArray.clear();
205 mLabelArray.clear();
206 }
207
209 void addLabel(unsigned int dataindex, LabelType const& label)
210 {
211 // refer to concrete specialized implementation
213 }
214
216 LabelView getLabels(int dataindex) { return LabelView(dataindex, mHeaderArray, mLabelArray); }
217
221 void fillVectorOfLabels(int dataindex, std::vector<LabelType>& v)
222 {
224 v.clear();
225 for (auto& e : getLabels(dataindex)) {
226 v.push_back(e);
227 }
228 }
229}; // end class
230
231} // namespace o2
232
233#endif
int32_t i
Class for time synchronization of RawReader instances.
bool operator==(const Iterator &rhs) const
bool operator!=(const Iterator &rhs) const
Iterator(std::vector< StoredLabelType > &v, int i)
Iterator & operator=(const Iterator &it)
constexpr LabelView(int i, std::vector< HeaderElement > &v1, std::vector< StoredLabelType > &v2)
std::vector< HeaderElement > mHeaderArray
static int lastIndex(HeaderElementContinuous const &h)
static LabelType & dereference(std::vector< LabelType > &v, int index)
void addLabel(unsigned int dataindex, LabelType const &label)
add a label for a dataindex
static void addLabelImpl(int dataindex, std::vector< HeaderElementContinuous > &headerv, std::vector< LabelType > &labelv, LabelType const &label)
static unsigned int getNextIndex(unsigned int index, std::vector< LabelType > const &)
void fillVectorOfLabels(int dataindex, std::vector< LabelType > &v)
static void addLabelImpl(int dataindex, std::vector< HeaderElementLinked > &headerv, std::vector< std::pair< LabelType, int > > &labelv, LabelType const &label)
static int lastIndex(HeaderElementLinked const &h)
LabelView getLabels(int dataindex)
get a container view on labels allowing use standard forward iteration in user code
static LabelType & dereference(std::vector< std::pair< LabelType, int > > &v, int index)
std::vector< StoredLabelType > mLabelArray
typename std::conditional< isContiguousStorage, LabelType, std::pair< LabelType, int > >::type StoredLabelType
typename std::conditional< isContiguousStorage, HeaderElementContinuous, HeaderElementLinked >::type HeaderElement
static unsigned int getNextIndex(unsigned int index, std::vector< std::pair< LabelType, int > > const &labels)
GLdouble n
Definition glcorearb.h:1982
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLfloat GLfloat v1
Definition glcorearb.h:812
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
Definition of a container to keep/associate and arbitrary number of labels associated to an index wit...
HeaderElementContinuous(unsigned short s, unsigned int i)
HeaderElementLinked(unsigned int i, int l, unsigned short s)