-
Notifications
You must be signed in to change notification settings - Fork 0
/
histogram_storage.h
132 lines (106 loc) · 3.11 KB
/
histogram_storage.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef HISTOGRAM_HISTSTORAGE_H_INCLUDED
#define HISTOGRAM_HISTSTORAGE_H_INCLUDED
#include "simple_hdf5.hpp"
#include <sstream>
#include <algorithm>
namespace histogram {
namespace detail {
// storage adapters for detail::view
template <typename T, size_t N>
const void*
get_data(const view<T,N> &d) { return d.data_; }
template <typename T, size_t N>
std::vector<hsize_t>
get_shape(const view<T,N> &d)
{
std::vector<hsize_t> shape(d.shape_.size());
std::copy(d.shape_.begin(), d.shape_.end(), shape.begin());
return std::move(shape);
}
template <typename T, size_t N>
hdf5::Datatype
get_datatype(const view<T,N> &d) { return hdf5::get_datatype(T()); }
}
// cribbed from: http://stackoverflow.com/a/11329249
namespace detail {
template<typename Iterable, bool rvalue>
class enumerate_object
{
private:
typedef typename std::conditional<rvalue, const Iterable&, Iterable>::type IterableType;
IterableType _iter;
std::size_t _size;
decltype(std::begin(_iter)) _begin;
const decltype(std::end(_iter)) _end;
public:
enumerate_object(const Iterable& iter):
_iter(iter),
_size(0),
_begin(std::begin(_iter)),
_end(std::end(_iter))
{}
enumerate_object(const Iterable&& iter):
_iter(std::move(iter)),
_size(0),
_begin(std::begin(_iter)),
_end(std::end(_iter))
{}
const enumerate_object& begin() const { return *this; }
const enumerate_object& end() const { return *this; }
bool operator!=(const enumerate_object&) const
{
return _begin != _end;
}
void operator++()
{
++_begin;
++_size;
}
auto operator*() const
-> std::pair<std::size_t, decltype(*_begin)>
{
return { _size, *_begin };
}
};
}
// lvalue; take a reference
template<typename Iterable>
detail::enumerate_object<Iterable, true> enumerate(const Iterable& iter)
{
return { iter };
}
// lvalue; adopt held object
template<typename Iterable>
detail::enumerate_object<Iterable, false> enumerate(const Iterable&& iter)
{
return { iter };
}
template <typename T>
void save(const T& hist, hdf5::File file, const std::string &where, const std::string &name, bool overwrite=false)
{
using namespace hdf5;
Group group = file.create_group(where, name, true);
auto attr = group.attrs();
attr["ndim"] = hist.ndim();
attr["nentries"] = hist.n_entries();
attr["title"] = hist.title();
file.create_carray(group, "_h_bincontent", hist.bincontent());
file.create_carray(group, "_h_squaredweights", hist.squaredweights());
for (const auto &pair : enumerate(hist.binedges())) {
std::ostringstream ss;
ss << "_h_binedges_" << pair.first;
file.create_carray(group, ss.str(), pair.second);
}
for (const auto &pair : enumerate(hist.labels())) {
std::ostringstream ss;
ss << "label_" << pair.first;
attr[ss.str()] = pair.second;
}
}
template <typename T>
void save(const T& hist, const std::string &fname, const std::string &where, const std::string &name, bool overwrite=false)
{
save(hist, hdf5::open_file(fname, hdf5::File::append), where, name, overwrite);
}
}
#endif // HISTOGRAM_HISTSTORAGE_H_INCLUDED