Skip to content

Commit 9de7c30

Browse files
authored
Introduced 2d arrays in Variant (#5132)
1 parent 1668597 commit 9de7c30

14 files changed

Lines changed: 501 additions & 117 deletions

Analysis/Tutorials/include/Analysis/configurableCut.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@
1111
#ifndef CONFIGURABLECUT_H
1212
#define CONFIGURABLECUT_H
1313

14+
#include "Framework/Array2D.h"
1415
#include <iosfwd>
1516
#include <Rtypes.h>
1617
#include <TMath.h>
1718

19+
static constexpr double default_matrix[3][3] = {{1.1, 1.2, 1.3}, {2.1, 2.2, 2.3}, {3.1, 3.2, 3.3}};
20+
1821
class configurableCut
1922
{
2023
public:
21-
configurableCut(float cut_ = 2., int state_ = 1, bool option_ = true, std::vector<float> bins_ = {0.5, 1.5, 2.5}, std::vector<std::string> labels_ = {"l1", "l2", "l3"})
22-
: cut{cut_}, state{state_}, option{option_}, bins{bins_}, labels{labels_}
24+
configurableCut(float cut_ = 2., int state_ = 1, bool option_ = true,
25+
std::vector<float> bins_ = {0.5, 1.5, 2.5},
26+
std::vector<std::string> labels_ = {"l1", "l2", "l3"},
27+
o2::framework::Array2D<double> cuts_ = {&default_matrix[0][0], 3, 3})
28+
: cut{cut_}, state{state_}, option{option_}, bins{bins_}, labels{labels_}, cuts{cuts_}
2329
{
2430
}
2531

@@ -40,14 +46,18 @@ class configurableCut
4046
void setLabels(std::vector<std::string> labels_);
4147
std::vector<std::string> getLabels() const;
4248

49+
void setCuts(o2::framework::Array2D<double> cuts_);
50+
o2::framework::Array2D<double> getCuts() const;
51+
4352
private:
4453
float cut;
4554
int state;
4655
bool option;
4756
std::vector<float> bins;
4857
std::vector<std::string> labels;
58+
o2::framework::Array2D<double> cuts;
4959

50-
ClassDef(configurableCut, 4);
60+
ClassDef(configurableCut, 5);
5161
};
5262

5363
std::ostream& operator<<(std::ostream& os, configurableCut const& c);

Analysis/Tutorials/src/configurableCut.cxx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
#include "Analysis/configurableCut.h"
1212
#include <iostream>
1313

14+
std::ostream& operator<<(std::ostream& os, configurableCut const& c)
15+
{
16+
os << "Cut value: " << c.getCut() << "; state: " << c.getState();
17+
return os;
18+
}
19+
1420
bool configurableCut::method(float arg) const
1521
{
1622
return arg > cut;
@@ -26,12 +32,6 @@ float configurableCut::getCut() const
2632
return cut;
2733
}
2834

29-
std::ostream& operator<<(std::ostream& os, configurableCut const& c)
30-
{
31-
os << "Cut value: " << c.getCut() << "; state: " << c.getState();
32-
return os;
33-
}
34-
3535
void configurableCut::setState(int state_)
3636
{
3737
state = state_;
@@ -54,19 +54,30 @@ bool configurableCut::getOption() const
5454

5555
void configurableCut::setBins(std::vector<float> bins_)
5656
{
57-
bins = bins_;
58-
};
57+
bins = std::move(bins_);
58+
}
59+
5960
std::vector<float> configurableCut::getBins() const
6061
{
6162
return bins;
62-
};
63+
}
6364

6465
void configurableCut::setLabels(std::vector<std::string> labels_)
6566
{
66-
labels = labels_;
67+
labels = std::move(labels_);
6768
}
6869

6970
std::vector<std::string> configurableCut::getLabels() const
7071
{
7172
return labels;
7273
}
74+
75+
void configurableCut::setCuts(o2::framework::Array2D<double> cuts_)
76+
{
77+
cuts = std::move(cuts_);
78+
}
79+
80+
o2::framework::Array2D<double> configurableCut::getCuts() const
81+
{
82+
return cuts;
83+
}

Analysis/Tutorials/src/configurableObjects.cxx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,41 @@ template <typename T>
2525
auto printArray(std::vector<T> const& vec)
2626
{
2727
std::stringstream ss;
28-
ss << "[";
29-
auto count = 0u;
30-
for (auto& entry : vec) {
31-
ss << entry;
32-
if (count < vec.size() - 1) {
33-
ss << ",";
34-
}
35-
++count;
28+
ss << "[" << vec[0];
29+
for (auto i = 1u; i < vec.size(); ++i) {
30+
ss << ", " << vec[i];
3631
}
3732
ss << "]";
3833
return ss.str();
3934
}
4035

36+
template <typename T>
37+
auto printMatrix(Array2D<T> const& m)
38+
{
39+
std::stringstream ss;
40+
ss << "[[" << m(0, 0);
41+
for (auto i = 1u; i < m.cols; ++i) {
42+
ss << "," << m(0, i);
43+
}
44+
for (auto i = 1u; i < m.rows; ++i) {
45+
ss << "], [" << m(i, 0);
46+
for (auto j = 1u; j < m.cols; ++j) {
47+
ss << "," << m(i, j);
48+
}
49+
}
50+
ss << "]]";
51+
return ss.str();
52+
}
53+
54+
static constexpr float defaultm[3][4] = {{1.1, 1.2, 1.3, 1.4}, {2.1, 2.2, 2.3, 2.4}, {3.1, 3.2, 3.3, 3.4}};
55+
4156
struct ConfigurableObjectDemo {
4257
Configurable<configurableCut> cut{"cut", {0.5, 1, true}, "generic cut"};
4358
MutableConfigurable<configurableCut> mutable_cut{"mutable_cut", {1., 2, false}, "generic cut"};
4459

4560
// note that size is fixed by this declaration - externally supplied vector needs to be the same size!
4661
Configurable<std::vector<int>> array{"array", {0, 0, 0, 0, 0, 0, 0}, "generic array"};
62+
Configurable<Array2D<float>> vmatrix{"matrix", {&defaultm[0][0], 3, 4}, "generic matrix"};
4763

4864
void init(InitContext const&){};
4965
void process(aod::Collision const&, aod::Tracks const& tracks)
@@ -53,7 +69,8 @@ struct ConfigurableObjectDemo {
5369
LOGF(INFO, "Cut1 labels: %s; Cut2 labels: %s", printArray(cut->getLabels()), printArray(mutable_cut->getLabels()));
5470
auto vec = (std::vector<int>)array;
5571
LOGF(INFO, "Array: %s", printArray(vec).c_str());
56-
for (auto& track : tracks) {
72+
LOGF(INFO, "Matrix: %s", printMatrix((Array2D<float>)vmatrix));
73+
for (auto const& track : tracks) {
5774
if (track.globalIndex() % 500 == 0) {
5875
std::string decision1;
5976
std::string decision2;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
#ifndef FRAMEWORK_ARRAY2D_H
11+
#define FRAMEWORK_ARRAY2D_H
12+
#include <cstdint>
13+
#include <vector>
14+
15+
namespace o2::framework
16+
{
17+
// matrix-like wrapper for std::vector
18+
// has no range checks
19+
template <typename T>
20+
struct Array2D {
21+
using element_t = T;
22+
23+
Array2D(T const* data_, uint32_t r, uint32_t c)
24+
: rows{r}, cols{c}
25+
{
26+
data = new T[rows * cols];
27+
for (auto i = 0U; i < rows; ++i) {
28+
for (auto j = 0U; j < cols; ++j) {
29+
data[i * cols + j] = *(data_ + (i * cols + j));
30+
}
31+
}
32+
}
33+
Array2D(std::vector<T> data_, uint32_t r, uint32_t c)
34+
: rows{r}, cols{c}
35+
{
36+
data = new T[rows * cols];
37+
for (auto i = 0U; i < rows; ++i) {
38+
for (auto j = 0U; j < cols; ++j) {
39+
data[i * cols + j] = data_[i * cols + j];
40+
}
41+
}
42+
}
43+
44+
Array2D(Array2D<T> const& other)
45+
: rows{other.rows},
46+
cols{other.cols}
47+
{
48+
data = new T[rows * cols];
49+
for (auto i = 0U; i < rows; ++i) {
50+
for (auto j = 0U; j < cols; ++j) {
51+
data[i * cols + j] = *(other.data + (i * cols + j));
52+
}
53+
}
54+
}
55+
56+
Array2D(Array2D<T>&& other)
57+
: rows{other.rows},
58+
cols{other.cols}
59+
{
60+
data = other.data;
61+
other.data = nullptr;
62+
other.rows = 0;
63+
other.cols = 0;
64+
}
65+
66+
Array2D& operator=(Array2D<T> const& other)
67+
{
68+
this->rows = other.rows;
69+
this->cols = other.cols;
70+
data = new T[rows * cols];
71+
for (auto i = 0U; i < rows; ++i) {
72+
for (auto j = 0U; j < cols; ++j) {
73+
data[i * cols + j] = *(other.data + (i * cols + j));
74+
}
75+
}
76+
return *this;
77+
}
78+
79+
Array2D& operator=(Array2D<T>&& other)
80+
{
81+
this->rows = other.rows;
82+
this->cols = other.cols;
83+
data = other.data;
84+
other.data = nullptr;
85+
other.rows = 0;
86+
other.cols = 0;
87+
return *this;
88+
}
89+
90+
~Array2D()
91+
{
92+
if (data != nullptr) {
93+
delete[] data;
94+
}
95+
}
96+
97+
T operator()(uint32_t y, uint32_t x) const
98+
{
99+
return data[y * cols + x];
100+
}
101+
T* operator[](uint32_t y) const
102+
{
103+
return data + y * cols;
104+
}
105+
106+
T* data = nullptr;
107+
uint32_t rows = 0;
108+
uint32_t cols = 0;
109+
};
110+
} // namespace o2::framework
111+
112+
#endif // FRAMEWORK_ARRAY2D_H

Framework/Core/include/Framework/ConfigParamRegistry.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace o2::framework
2525
namespace
2626
{
2727
template <typename T>
28-
std::vector<T> extractVector(boost::property_tree::ptree& tree)
28+
std::vector<T> extractVector(boost::property_tree::ptree const& tree)
2929
{
3030
std::vector<T> result(tree.size());
3131
auto count = 0u;
@@ -34,6 +34,29 @@ std::vector<T> extractVector(boost::property_tree::ptree& tree)
3434
}
3535
return result;
3636
}
37+
38+
template <typename T>
39+
o2::framework::Array2D<T> extractMatrix(boost::property_tree::ptree const& tree)
40+
{
41+
std::vector<T> cache;
42+
uint32_t nrows = tree.size();
43+
uint32_t ncols = 0;
44+
bool first = true;
45+
auto irow = 0u;
46+
for (auto& row : tree) {
47+
if (first) {
48+
ncols = row.second.size();
49+
first = false;
50+
}
51+
auto icol = 0u;
52+
for (auto& entry : row.second) {
53+
cache.push_back(entry.second.get_value<T>());
54+
++icol;
55+
}
56+
++irow;
57+
}
58+
return o2::framework::Array2D<T>{cache, nrows, ncols};
59+
}
3760
} // namespace
3861

3962
class ConfigParamStore;
@@ -80,6 +103,8 @@ class ConfigParamRegistry
80103
return std::string_view{mStore->store().get<std::string>(key)};
81104
} else if constexpr (is_base_of_template<std::vector, T>::value) {
82105
return extractVector<typename T::value_type>(mStore->store().get_child(key));
106+
} else if constexpr (is_base_of_template<o2::framework::Array2D, T>::value) {
107+
return extractMatrix<typename T::element_t>(mStore->store().get_child(key));
83108
} else if constexpr (std::is_same_v<T, boost::property_tree::ptree>) {
84109
return mStore->store().get_child(key);
85110
} else if constexpr (std::is_constructible_v<T, boost::property_tree::ptree>) {

Framework/Core/include/Framework/ConfigParamsHelper.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct ConfigParamsHelper {
3434
/// all options which are found in the vetos are skipped
3535
static bool dpl2BoostOptions(const std::vector<ConfigParamSpec>& spec,
3636
options_description& options,
37-
options_description vetos = options_description());
37+
boost::program_options::options_description vetos = options_description());
3838

3939
/// populate boost program options for a complete workflow
4040
template <typename ContainerType>
@@ -119,7 +119,10 @@ struct ConfigParamsHelper {
119119
V == VariantType::ArrayFloat ||
120120
V == VariantType::ArrayDouble ||
121121
V == VariantType::ArrayBool ||
122-
V == VariantType::ArrayString) {
122+
V == VariantType::ArrayString ||
123+
V == VariantType::MatrixInt ||
124+
V == VariantType::MatrixFloat ||
125+
V == VariantType::MatrixDouble) {
123126
auto value = boost::program_options::value<std::string>();
124127
value = value->default_value(spec.defaultValue.asString());
125128
if constexpr (V != VariantType::String) {

0 commit comments

Comments
 (0)