Project
Loading...
Searching...
No Matches
DigitBlockBase.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//
12//file DigitBlockBase.h base class for processing RAW data into Digits
13//
14// Artur.Furs
15// afurs@cern.ch
16
17#ifndef ALICEO2_FIT_DIGITBLOCKBASE_H_
18#define ALICEO2_FIT_DIGITBLOCKBASE_H_
19#include <iostream>
20#include <vector>
21#include <algorithm>
22#include <type_traits>
23#include <utility>
24#include <array>
25#include <Rtypes.h>
28#include <Framework/Logger.h>
29#include <boost/mpl/vector.hpp>
30#include <boost/mpl/front.hpp>
31#include <boost/mpl/fold.hpp>
32#include <boost/mpl/remove_if.hpp>
33#include <boost/mpl/lambda.hpp>
34#include <boost/mpl/not.hpp>
35#include <boost/mpl/size.hpp>
36
37#include <gsl/span>
38namespace o2
39{
40namespace fit
41{
42
43namespace DigitBlockHelper
44{
45//Check template specialisation
46//Is there analog of this metafunction in Common O2 lib?
47template <template <typename...> class Template, typename T>
48struct IsSpecOfType : std::false_type {
49};
50template <template <typename...> class Template, typename... T>
51struct IsSpecOfType<Template, Template<T...>> : std::true_type {
52};
53//Check if RangeReference is a single field in main digit structure
54template <typename T, typename = void>
55struct HasRef : std::false_type {
56};
57//For FT0
58template <typename T>
59struct HasRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename o2::dataformats::RangeReference<int, int>>::value>> : std::true_type {
60};
61//For FV0
62template <typename T>
63struct HasRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename o2::dataformats::RangeRefComp<6>>::value>> : std::true_type {
64};
65//For FDD
66template <typename T>
67struct HasRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename o2::dataformats::RangeRefComp<5>>::value>> : std::true_type {
68};
69
70//Check if RangeReference is an array field in main digit structure
71template <typename T, typename = void>
72struct HasArrayRef : std::false_type {
73};
74//For FT0
75template <typename T>
76struct HasArrayRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename std::array<typename o2::dataformats::RangeReference<int, int>, std::tuple_size<decltype(std::declval<T>().ref)>::value>>::value>> : std::true_type {
77};
78//For FV0
79template <typename T>
80struct HasArrayRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename std::array<typename o2::dataformats::RangeRefComp<6>, std::tuple_size<decltype(std::declval<T>().ref)>::value>>::value>> : std::true_type {
81};
82//For FDD
83template <typename T>
84struct HasArrayRef<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ref), typename std::array<typename o2::dataformats::RangeRefComp<5>, std::tuple_size<decltype(std::declval<T>().ref)>::value>>::value>> : std::true_type {
85};
86
87//Get RangeReference number of dimentions.
88template <typename T, typename = void>
90 constexpr static std::size_t value = 0;
91};
92template <typename T>
93struct GetDigitRefsN<T, std::enable_if_t<HasRef<T>::value>> {
94 constexpr static std::size_t value = 1;
95};
96template <typename T>
97struct GetDigitRefsN<T, std::enable_if_t<HasArrayRef<T>::value && (std::tuple_size<decltype(std::declval<T>().ref)>::value > 1)>> {
98 constexpr static std::size_t value = std::tuple_size<decltype(std::declval<T>().ref)>::value;
99};
100//Check if InteractionRecord field exists
101template <typename T, typename = void>
102struct HasIntRecord : std::false_type {
103};
104template <typename T>
105struct HasIntRecord<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().mIntRecord), o2::InteractionRecord>::value>> : std::true_type {
106};
107//Temporary for FV0
108template <typename T>
109struct HasIntRecord<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().ir), o2::InteractionRecord>::value>> : std::true_type {
110};
111//Dividing to sub-digit structures with InteractionRecord(single one, e.g. for TCM extended mode) and without
112template <typename T>
113using GetVecSubDigit = typename boost::mpl::remove_if<T, boost::mpl::lambda<HasIntRecord<boost::mpl::_1>>::type>::type;
114template <typename T>
115using GetVecSingleSubDigit = typename boost::mpl::remove_if<T, boost::mpl::lambda<boost::mpl::not_<HasIntRecord<boost::mpl::_1>>>::type>::type;
116//Converting empty Boost MPL vector to empty std::tuple
117template <typename T, typename = void>
119 typedef std::tuple<> type;
120 typedef std::tuple<> vector_type;
121 constexpr static bool sIsEmpty = true;
122 constexpr static bool sIsTuple = true;
123 constexpr static std::size_t size = 0;
124};
125//Converting Boost MPL vector with 1 element to std::vector
126template <typename T>
127struct GetSubDigitField<T, std::enable_if_t<boost::mpl::size<T>::value == 1>> {
128 typedef std::vector<typename boost::mpl::front<T>::type> vector_type;
129 typedef typename boost::mpl::front<T>::type type;
130 constexpr static bool sIsEmpty = false;
131 constexpr static bool sIsTuple = false;
132 constexpr static std::size_t size = 1;
133};
134//
135//Converting Boost MPL vector to std::tuple of std::vectors
136template <typename T>
137struct GetSubDigitField<T, std::enable_if_t<(boost::mpl::size<T>::value > 1)>> {
138 template <typename Arg1, typename Arg2>
139 struct MakeTuple;
140 template <typename... Args, typename LastArg>
141 struct MakeTuple<std::tuple<Args...>, LastArg> {
142 typedef std::tuple<Args..., LastArg> type;
143 };
144 typedef typename boost::mpl::fold<T, std::tuple<>, MakeTuple<boost::mpl::_1, std::vector<boost::mpl::_2>>>::type vector_type;
145 typedef typename boost::mpl::fold<T, std::tuple<>, MakeTuple<boost::mpl::_1, boost::mpl::_2>>::type type;
146 constexpr static bool sIsEmpty = false;
147 constexpr static bool sIsTuple = true;
148 constexpr static std::size_t size = boost::mpl::size<T>::value;
149};
150
151} // namespace DigitBlockHelper
152
153// DigitBlock - digit block, for interacting with Digits structures as one
154// Digit - primary digit struct which should contain InteractionRecord field and ReferenceRange to SubDigit(not all of them)
155// SubDigit - sub digit structure which shouldn't contain InteractionRecord field
156// SingleSubDigit - separated SubDigits which contain InteractionRecord field and not referred by ReferenceRange field in Digit structure.
157// For example extended TCM mode uses such SingleSubDigits
158template <typename DigitType, typename... SubDigitTypes>
159class DigitBlockBase //:public DigitBlock
160{
161 public:
163 {
164 mDigit.setIntRecord(intRec);
165 // mSubDigit.reserve(256);
166 }
167 DigitBlockBase(const DigitType& digit) : mDigit(digit)
168 {
169 }
170 DigitBlockBase() = default;
172 ~DigitBlockBase() = default;
173 typedef DigitType Digit_t;
174 typedef std::tuple<std::vector<DigitType>, std::vector<SubDigitTypes>...> TupleVecDigitObjs_t;
175 typedef boost::mpl::vector<SubDigitTypes...> VecAllSubDigit_t;
185 template <typename VecDigit, typename... VecSubDigits>
186 auto getSubDigits(VecDigit& vecDigits, VecSubDigits&... vecSubDigits)
187 -> std::enable_if_t<sizeof...(VecSubDigits) == sNSubDigits>
188 {
189 if constexpr (sNSubDigits > 0) {
190 getSubDigit<sizeof...(VecSubDigits), sizeof...(VecSubDigits)>(std::tie(vecSubDigits...));
191 }
192 vecDigits.push_back(std::move(mDigit));
193 }
194
195 template <typename... T>
196 auto getSingleSubDigits(T&... vecSingleSubDigits)
197 -> std::enable_if_t<sizeof...(T) == sNSingleSubDigits>
198 {
199 if constexpr (sNSingleSubDigits > 0) {
200 getSingleSubDigit<sizeof...(T), sizeof...(T)>(std::tie(vecSingleSubDigits...));
201 }
202 }
203
204 template <std::size_t N, std::size_t N_TOTAL, typename... T>
205 auto getSubDigit(std::tuple<T...> tupleVecSubDigits) -> std::enable_if_t<(N_TOTAL > 1)>
206 {
207 mDigit.ref[N - 1].set(std::get<N - 1>(tupleVecSubDigits).size(), std::get<N - 1>(mSubDigit).size());
208 std::move(std::get<N - 1>(mSubDigit).begin(), std::get<N - 1>(mSubDigit).end(), std::back_inserter(std::get<N - 1>(tupleVecSubDigits)));
209 if constexpr (N > 1) {
210 getSubDigit<N - 1, N_TOTAL>(tupleVecSubDigits);
211 }
212 }
213 template <std::size_t N, std::size_t N_TOTAL, typename... T>
214 auto getSubDigit(std::tuple<T...> tupleVecSubDigits) -> std::enable_if_t<(N_TOTAL == 1)>
215 {
216 mDigit.ref.set(std::get<0>(tupleVecSubDigits).size(), mSubDigit.size());
217 std::move(mSubDigit.begin(), mSubDigit.end(), std::back_inserter(std::get<0>(tupleVecSubDigits)));
218 }
219
220 template <std::size_t N, std::size_t N_TOTAL, typename... T>
221 auto getSingleSubDigit(std::tuple<T...> tupleVecSingleSubDigits) -> std::enable_if_t<(N_TOTAL > 1)>
222 {
223 std::get<N - 1>(tupleVecSingleSubDigits).push_back(std::move(std::get<N - 1>(mSingleSubDigit)));
224 if constexpr (N > 1) {
225 getSingleSubDigit<N - 1, N_TOTAL>(tupleVecSingleSubDigits);
226 }
227 }
228 template <std::size_t N, std::size_t N_TOTAL, typename... T>
229 auto getSingleSubDigit(std::tuple<T...> tupleVecSingleSubDigits) -> std::enable_if_t<(N_TOTAL == 1)>
230 {
231 std::get<0>(tupleVecSingleSubDigits).push_back(std::move(mSingleSubDigit));
232 }
233 // 1-Dim SubDigit
234 template <typename DigitBlockType, typename DigitT, typename SubDigitT>
235 static auto makeDigitBlock(const std::vector<DigitT>& vecDigits, const std::vector<SubDigitT>& vecSubDigits) -> std::enable_if_t<DigitBlockHelper::GetDigitRefsN<DigitT>::value == 1 && DigitBlockHelper::IsSpecOfType<DigitBlockBase, typename DigitBlockType::DigitBlockBase_t>::value, std::vector<DigitBlockType>>
236 {
237 std::vector<DigitBlockType> vecResult;
238 vecResult.reserve(vecDigits.size());
239 for (const auto& digit : vecDigits) {
240 auto itBegin = vecSubDigits.begin();
241 std::advance(itBegin, digit.ref.getFirstEntry());
242 auto itLast = itBegin;
243 std::advance(itLast, digit.ref.getEntries());
244 vecResult.push_back({digit});
245 vecResult.back().mSubDigit.reserve(digit.ref.getEntries());
246 std::copy(itBegin, itLast, std::back_inserter(vecResult.back().mSubDigit));
247 }
248 return vecResult;
249 }
250
251 // Multi-Dim SubDigits
252 template <typename DigitBlockType, typename DigitT, typename... SubDigitT>
253 static auto makeDigitBlock(const std::vector<DigitT>& vecDigits, const std::vector<SubDigitT>&... vecSubDigits) -> std::enable_if_t<(DigitBlockHelper::GetDigitRefsN<DigitT>::value > 1) && (DigitBlockHelper::IsSpecOfType<DigitBlockBase, typename DigitBlockType::DigitBlockBase_t>::value), std::vector<DigitBlockType>>
254 {
255 std::vector<DigitBlockType> vecResult;
256 vecResult.reserve(vecDigits.size());
257 for (const auto& digit : vecDigits) {
258 vecResult.push_back({digit});
259 auto& refTuple = vecResult.back().mSubDigit;
260 fillSubDigitTuple<sizeof...(SubDigitT)>(digit, std::tie(vecSubDigits...), refTuple);
261 }
262 return vecResult;
263 }
264
265 template <std::size_t N, typename DigitT, typename... T>
266 static void fillSubDigitTuple(const DigitT& digit, const std::tuple<T...>& tupleSrc, std::tuple<T...>& tupleDest)
267 {
268 const auto& vecSrc = std::get<N>(tupleSrc);
269 auto& vecDest = std::get<N>(tupleSrc);
270 auto itBegin = vecSrc.begin();
271 std::advance(itBegin, digit.ref[N - 1].getFirstEntry());
272 auto itLast = itBegin;
273 std::advance(itLast, digit.ref[N - 1].getEntries());
274 vecDest.reserve(digit.ref[N - 1].getEntries());
275 std::copy(itBegin, itLast, std::back_inserter(vecDest));
276 if constexpr (N > 1) {
277 fillSubDigitTuple<N - 1>(digit, tupleSrc, tupleDest);
278 }
279 }
280 void print() const
281 {
282 mDigit.printLog();
283 if constexpr (DigitBlockHelper::IsSpecOfType<std::tuple, decltype(mSubDigit)>::value) {
284 if constexpr ((std::tuple_size<decltype(mSubDigit)>::value) > 1) {
285 LOG(info) << "______________SUB DIGITS____________";
286 std::apply([](const auto&... vecSubDigit) {
287 ((std::for_each(vecSubDigit.begin(), vecSubDigit.end(), [](const auto& subDigit) {
288 subDigit.printLog();
289 })),
290 ...);
291 },
292 mSubDigit);
293 }
294 } else {
295 LOG(info) << "______________SUB DIGITS____________";
296 std::for_each(mSubDigit.begin(), mSubDigit.end(), [](const auto& subDigit) {
297 subDigit.printLog();
298 });
299 }
300 if constexpr (DigitBlockHelper::IsSpecOfType<std::tuple, decltype(mSingleSubDigit)>::value) {
301 if constexpr ((std::tuple_size<decltype(mSingleSubDigit)>::value) > 1) {
302 LOG(info) << "______________SINGLE SUB DIGITS____________";
303 std::apply([](const auto&... singleSubDigit) {
304 ((singleSubDigit.printLog()), ...);
305 },
307 }
308 } else {
309 LOG(info) << "______________SINGLE SUB DIGITS____________";
310 mSingleSubDigit.printLog();
311 }
312 LOG(info) << std::dec;
313 LOG(info) << "______________________________________";
314 }
315};
316
317} // namespace fit
318} // namespace o2
319#endif
Class to refer to the 1st entry and N elements of some group in the continuous container.
static constexpr std::size_t sNSubDigits
auto getSubDigits(VecDigit &vecDigits, VecSubDigits &... vecSubDigits) -> std::enable_if_t< sizeof...(VecSubDigits)==sNSubDigits >
DigitBlockBase(const DigitType &digit)
auto getSubDigit(std::tuple< T... > tupleVecSubDigits) -> std::enable_if_t<(N_TOTAL > 1)>
DigitBlockHelper::GetVecSingleSubDigit< VecAllSubDigit_t > VecSingleSubDigit_t
DigitBlockHelper::GetVecSubDigit< VecAllSubDigit_t > VecSubDigit_t
DigitBlockBase(const DigitBlockBase &other)=default
DigitBlockHelper::GetSubDigitField< VecSingleSubDigit_t >::type SingleSubDigit_t
static void fillSubDigitTuple(const DigitT &digit, const std::tuple< T... > &tupleSrc, std::tuple< T... > &tupleDest)
static auto makeDigitBlock(const std::vector< DigitT > &vecDigits, const std::vector< SubDigitT > &... vecSubDigits) -> std::enable_if_t<(DigitBlockHelper::GetDigitRefsN< DigitT >::value > 1) &&(DigitBlockHelper::IsSpecOfType< DigitBlockBase, typename DigitBlockType::DigitBlockBase_t >::value), std::vector< DigitBlockType > >
auto getSingleSubDigits(T &... vecSingleSubDigits) -> std::enable_if_t< sizeof...(T)==sNSingleSubDigits >
auto getSingleSubDigit(std::tuple< T... > tupleVecSingleSubDigits) -> std::enable_if_t<(N_TOTAL > 1)>
std::tuple< std::vector< DigitType >, std::vector< SubDigitTypes >... > TupleVecDigitObjs_t
static constexpr std::size_t sNSingleSubDigits
SingleSubDigit_t mSingleSubDigit
auto getSubDigit(std::tuple< T... > tupleVecSubDigits) -> std::enable_if_t<(N_TOTAL==1)>
DigitBlockBase(const o2::InteractionRecord &intRec)
boost::mpl::vector< SubDigitTypes... > VecAllSubDigit_t
auto getSingleSubDigit(std::tuple< T... > tupleVecSingleSubDigits) -> std::enable_if_t<(N_TOTAL==1)>
DigitBlockHelper::GetSubDigitField< VecSubDigit_t >::vector_type SubDigit_t
static auto makeDigitBlock(const std::vector< DigitT > &vecDigits, const std::vector< SubDigitT > &vecSubDigits) -> std::enable_if_t< DigitBlockHelper::GetDigitRefsN< DigitT >::value==1 &&DigitBlockHelper::IsSpecOfType< DigitBlockBase, typename DigitBlockType::DigitBlockBase_t >::value, std::vector< DigitBlockType > >
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
typename boost::mpl::remove_if< T, boost::mpl::lambda< boost::mpl::not_< HasIntRecord< boost::mpl::_1 > > >::type >::type GetVecSingleSubDigit
typename boost::mpl::remove_if< T, boost::mpl::lambda< HasIntRecord< boost::mpl::_1 > >::type >::type GetVecSubDigit
TFitResultPtr fit(const size_t nBins, const T *arr, const T xMin, const T xMax, TF1 &func, std::string_view option="")
Definition fit.h:59
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
boost::mpl::fold< T, std::tuple<>, MakeTuple< boost::mpl::_1, std::vector< boost::mpl::_2 > > >::type vector_type
boost::mpl::fold< T, std::tuple<>, MakeTuple< boost::mpl::_1, boost::mpl::_2 > >::type type
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"