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