R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
Mille.cxx
Go to the documentation of this file.
1#include "Mille.h"
2#include "MilleEntry.h"
3#include <cstddef>
4#include <fmt/base.h>
5#include <fmt/core.h>
6#include <fmt/format.h>
7#include <fmt/ranges.h>
8#include <fstream>
9#include <iostream>
10#include <stdexcept>
11#include <string_view>
12#include <utility>
13#include <vector>
14
15#ifdef HAS_CPP_STANDARD_17
16#include <range/v3/view/enumerate.hpp>
17#include <range/v3/view/filter.hpp>
18namespace stdrng = ranges;
19#else
20#include <ranges>
21namespace stdrng = std::ranges;
22#endif
23
24namespace
25{
26 template <typename T>
27 inline auto get_size_in_bytes()
28 {
29 return static_cast<std::streamsize>(sizeof(T));
30 }
31
32 template <typename T>
33 inline auto get_size_in_bytes(const std::vector<T>& data)
34 {
35 return static_cast<std::streamsize>(sizeof(T) * data.size());
36 }
37
38} // namespace
39
40namespace R3B
41{
42 Mille::Mille(std::string_view outFileName, bool asBinary, bool writeZero)
43 : is_binary_(asBinary)
44 , is_zero_written_(writeZero)
45 {
46 output_file_.open(
47 outFileName.data(),
48 (asBinary ? (std::ios::binary | std::ios::out | std::ios::trunc) : std::ios::out | std::ios::trunc));
49 if (!output_file_.is_open())
50 {
51 throw std::runtime_error(fmt::format("Mille::Mille: Could not open {} as output file.", outFileName));
52 }
53 }
54
55 void Mille::mille(const MilleDataPoint& data_point)
56 {
57 if (data_point.sigma <= 0.)
58 {
59 return;
60 }
61
62 check_buffer_size(data_point.locals.size(), data_point.globals.size());
63
64 if (buffer_.get_current_size() == 0)
65 {
66 buffer_.add_entry(0, 0.);
67 }
68
69 buffer_.add_entry(0, data_point.measurement);
70
71 for (const auto [index, value] :
72 stdrng::views::enumerate(data_point.locals) |
73 stdrng::views::filter([this](const auto& index_deriv) -> bool
74 { return std::get<1>(index_deriv) != 0 or is_zero_written_; }))
75 {
76 buffer_.add_entry(static_cast<int>(index + 1), value);
77 }
78
79 buffer_.add_entry(0, data_point.sigma);
80
81 for (const auto& [label, deriv] : data_point.globals)
82 {
83 if (deriv != 0 or is_zero_written_)
84 {
85 if ((label > 0 or is_zero_written_) and label <= max_label_size_)
86 {
87 buffer_.add_entry(label, deriv);
88 }
89 else
90 {
91 fmt::println(stderr, "Mille::mille: Invalid label {} <= 0 or > ", label);
92 }
93 }
94 }
95 }
96
97 void Mille::special(const std::vector<std::pair<int, float>>& special_data)
98 {
99 if (special_data.empty())
100 {
101 return;
102 }
104 {
105 throw std::logic_error("Mille::special: Special values already stored for this record.");
106 }
107 if (buffer_.get_current_size() == 0)
108 {
109 buffer_.add_entry(0, 0.);
110 }
111
112 buffer_.add_entry(0, 0.);
113 buffer_.add_entry(0, -static_cast<float>(special_data.size()));
114 for (const auto& [index, value] : special_data)
115 {
116 buffer_.add_entry(index, value);
117 }
118 has_special_done_ = true;
119 }
120
122 {
123 if (buffer_.is_empty())
124 {
125 return;
126 }
129 reset();
130 }
131
133 {
134 const auto data_size = static_cast<int>(buffer_.get_current_size());
135 output_file_.write(reinterpret_cast<const char*>(&data_size), get_size_in_bytes<decltype(data_size)>());
136 output_file_.write(reinterpret_cast<const char*>(buffer_.get_values().data()),
137 get_size_in_bytes(buffer_.get_values()));
138 output_file_.write(reinterpret_cast<const char*>(buffer_.get_indices().data()),
139 get_size_in_bytes(buffer_.get_indices()));
140 }
141
143 {
144 output_file_ << buffer_.get_current_size() << "\n";
145 output_file_ << fmt::format("{}\n", fmt::join(buffer_.get_indices(), " "));
146 output_file_ << fmt::format("{}\n", fmt::join(buffer_.get_values(), " "));
147 }
148
150 {
151 buffer_.clear();
152 has_special_done_ = false;
153 }
154
155 void Mille::close() { output_file_.close(); }
156 void Mille::check_buffer_size(std::size_t nLocal, std::size_t nGlobal)
157 {
158 if (buffer_.get_current_size() >= max_buffer_size_)
159 {
160 throw std::runtime_error(
161 fmt::format("Mille::checkBufferSize: Buffer too short ({}), \n need space for nLocal ({}) \nGlobal "
162 "({}) local/global derivatives, {} already stored!",
164 nLocal,
165 nGlobal,
166 buffer_.get_current_size()));
167 }
168 }
169} // namespace R3B
void write_to_non_binary()
Definition Mille.cxx:142
bool has_special_done_
if true, special(..) already called for this record
Definition Mille.h:77
void mille(const MilleDataPoint &data_point)
Write the MilleDataPoint structure to the internal data buffer of the type MilleBuffer.
Definition Mille.cxx:55
void check_buffer_size(std::size_t nLocal, std::size_t nGlobal)
Definition Mille.cxx:156
Mille(std::string_view outFileName, bool asBinary=true, bool writeZero=false)
Definition Mille.cxx:42
void close()
Definition Mille.cxx:155
std::ofstream output_file_
C-binary for output.
Definition Mille.h:82
bool is_binary_
if false output as text
Definition Mille.h:78
static constexpr unsigned int max_label_size_
Definition Mille.h:85
std::size_t max_buffer_size_
Maximum size of the data buffer.
Definition Mille.h:81
bool is_zero_written_
if true also write out derivatives/labels ==0
Definition Mille.h:79
void write_to_binary()
Definition Mille.cxx:132
void reset()
Definition Mille.cxx:149
MilleBuffer< int, float > buffer_
Data buffer to store the points of the events.
Definition Mille.h:80
void special(const std::vector< std::pair< int, float > > &special_data)
Definition Mille.cxx:97
void end()
Streaming an entry data to the output file.
Definition Mille.cxx:121
uint64_t num_of_entries_
Definition Mille.h:83
std::vector< std::pair< int, float > > globals
Definition MilleEntry.h:27
std::vector< float > locals
Definition MilleEntry.h:26