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