McStas Readout Master 0.8.0
Loading...
Searching...
No Matches
hdf_interface.h
1#pragma once
2#include <chrono>
3#include <thread>
4
5#include <highfive/H5File.hpp>
6#include <highfive/H5DataSet.hpp>
7#include <highfive/H5DataSpace.hpp>
8
9#include "Readout.h"
11#include "enums.h"
12
13#ifdef WIN32
14// Export symbols if compile flags "READOUT_SHARED" and "READOUT_EXPORT" are set on Windows.
15 #ifdef READOUT_SHARED
16 #ifdef READOUT_EXPORT
17 #define RL_API __declspec(dllexport)
18 #else
19 #define RL_API __declspec(dllimport)
20 #endif
21 #else
22 // Disable definition if linking statically.
23 #define RL_API
24 #endif
25#else
26// Disable definition for non-Win32 systems.
27#define RL_API
28#endif
29
33class RL_API Event{
34public:
35 uint8_t ring;
36 uint8_t fen;
37 double time;
38 double weight;
39 Event() = default;
40 Event(uint8_t ring, uint8_t fen, double time, double weight)
41 : ring(ring), fen(fen), time(time), weight(weight) {}
42};
43
45class RL_API CAEN_event: public Event {
46public:
47 uint8_t channel;
48 uint16_t a;
49 uint16_t b;
50 uint16_t c;
51 uint16_t d;
52 explicit CAEN_event() = default;
53 CAEN_event(uint8_t r, uint8_t f, double t, double w, const CAEN_readout * ro)
54 : Event(r, f, t, w), channel{ro->channel}, a{ro->a}, b{ro->b}, c{ro->c}, d{ro->d} {}
55 template<class T> void add(T & readout) const {
56 auto r = CAEN_readout{channel, a, b, c, d};
57 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
58// std::this_thread::sleep_for(std::chrono::milliseconds(10));
59 }
60};
61
63class RL_API CDT_event: public Event {
64public:
65 uint8_t om;
66 uint8_t cathode;
67 uint8_t anode;
68 explicit CDT_event() = default;
69 CDT_event(uint8_t r, uint8_t f, double t, double w, const CDT_readout * p)
70 : Event(r, f, t, w), om{p->om}, cathode{p->cathode}, anode{p->anode} {}
71 template<class T> void add(T & readout) const {
72 auto r = CDT_readout{om, cathode, anode};
73 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
74// std::this_thread::sleep_for(std::chrono::milliseconds(10));
75 }
76};
77
79class RL_API VMM3_event: public Event {
80public:
81 uint16_t bc;
82 uint16_t otadc;
83 uint8_t geo;
84 uint8_t tdc;
85 uint8_t vmm;
86 uint8_t channel;
87 explicit VMM3_event() = default;
88 VMM3_event(uint8_t r, uint8_t f, double t, double w, const VMM3_readout * p)
89 : Event(r, f, t, w), bc{p->bc}, otadc{p->otadc}, geo{p->geo}, tdc{p->tdc}, vmm{p->vmm}, channel{p->channel} {}
90 template<class T> void add(T & readout) const {
91 auto r = VMM3_readout{bc, otadc, geo, tdc, vmm, channel};
92 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
93// std::this_thread::sleep_for(std::chrono::milliseconds(10));
94 }
95};
96
98class RL_API BM0_event: public Event {
99public:
100 uint8_t channel;
101 explicit BM0_event() = default;
102 BM0_event(uint8_t r, uint8_t f, double t, double w, const BM0_readout * p)
103 : Event(r, f, t, w), channel{p->channel} {}
104 template<class T> void add(T & readout) const {
105 auto r = BM0_readout{channel};
106 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
107 }
108};
109
111class RL_API BM2_event: public Event {
112public:
113 uint8_t channel;
114 uint16_t pos_x;
115 uint16_t pos_y;
116 explicit BM2_event() = default;
117 BM2_event(uint8_t r, uint8_t f, double t, double w, const BM2_readout * p)
118 : Event(r, f, t, w), channel{p->channel} , pos_x{p->pos_x}, pos_y{p->pos_y} {}
119 template<class T> void add(T & readout) const {
120 auto r = BM2_readout{channel, pos_x, pos_y};
121 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
122 }
123};
124
126class RL_API BMI_event: public Event {
127public:
128 uint8_t channel;
129 uint8_t sum;
130 uint32_t adc; // 24 bit ADC value, but stored in a 32-bit integer for alignment reasons
131 explicit BMI_event() = default;
132 BMI_event(uint8_t r, uint8_t f, double t, double w, const BMI_readout * p)
133 : Event(r, f, t, w), channel{p->channel} , sum{p->sum}, adc{p->adc} {}
134 template<class T> void add(T & readout) const {
135 auto r = BMI_readout{channel, sum, adc};
136 readout.addReadout(ring, fen, time, weight, static_cast<void *>(&r));
137 }
138};
139
140
141inline HighFive::CompoundType create_compound_caen_readout(){
142 return {
143 {"ring", HighFive::create_datatype<uint8_t>()},
144 {"FEN", HighFive::create_datatype<uint8_t>()},
145 {"time", HighFive::create_datatype<double>()},
146 {"weight", HighFive::create_datatype<double>()},
147 {"channel", HighFive::create_datatype<uint8_t>()},
148 {"a", HighFive::create_datatype<uint16_t>()},
149 {"b", HighFive::create_datatype<uint16_t>()},
150 {"c", HighFive::create_datatype<uint16_t>()},
151 {"d", HighFive::create_datatype<uint16_t>()},
152 };
153}
154
155inline HighFive::CompoundType create_compound_dream_readout(){
156 return {
157 {"ring", HighFive::create_datatype<uint8_t>()},
158 {"FEN", HighFive::create_datatype<uint8_t>()},
159 {"time", HighFive::create_datatype<double>()},
160 {"weight", HighFive::create_datatype<double>()},
161 {"om", HighFive::create_datatype<uint8_t>()},
162 {"cathode", HighFive::create_datatype<uint8_t>()},
163 {"anode", HighFive::create_datatype<uint8_t>()},
164 };
165}
166
167inline HighFive::CompoundType create_compound_vmm3_readout(){
168 return {
169 {"ring", HighFive::create_datatype<uint8_t>()},
170 {"FEN", HighFive::create_datatype<uint8_t>()},
171 {"time", HighFive::create_datatype<double>()},
172 {"weight", HighFive::create_datatype<double>()},
173 {"bc", HighFive::create_datatype<uint16_t>()},
174 {"otadc", HighFive::create_datatype<uint16_t>()},
175 {"geo", HighFive::create_datatype<uint8_t>()},
176 {"tdc", HighFive::create_datatype<uint8_t>()},
177 {"vmm", HighFive::create_datatype<uint8_t>()},
178 {"channel", HighFive::create_datatype<uint8_t>()},
179 };
180}
181
182inline HighFive::CompoundType create_compound_bm0_readout(){
183 return {
184 {"ring", HighFive::create_datatype<uint8_t>()},
185 {"FEN", HighFive::create_datatype<uint8_t>()},
186 {"time", HighFive::create_datatype<double>()},
187 {"weight", HighFive::create_datatype<double>()},
188 {"channel", HighFive::create_datatype<uint8_t>()},
189 };
190}
191
192inline HighFive::CompoundType create_compound_bm2_readout(){
193 return {
194 {"ring", HighFive::create_datatype<uint8_t>()},
195 {"FEN", HighFive::create_datatype<uint8_t>()},
196 {"time", HighFive::create_datatype<double>()},
197 {"weight", HighFive::create_datatype<double>()},
198 {"channel", HighFive::create_datatype<uint8_t>()},
199 {"pos_x", HighFive::create_datatype<uint16_t>()},
200 {"pos_y", HighFive::create_datatype<uint16_t>()},
201 };
202}
203
204inline HighFive::CompoundType create_compound_bmi_readout(){
205 return {
206 {"ring", HighFive::create_datatype<uint8_t>()},
207 {"FEN", HighFive::create_datatype<uint8_t>()},
208 {"time", HighFive::create_datatype<double>()},
209 {"weight", HighFive::create_datatype<double>()},
210 {"channel", HighFive::create_datatype<uint8_t>()},
211 {"sum", HighFive::create_datatype<uint8_t>()},
212 {"adc", HighFive::create_datatype<uint32_t>()},
213 };
214}
215
216namespace HighFive {
217 template<> inline DataType create_datatype<CAEN_event>(){return create_compound_caen_readout();}
218 template<> inline DataType create_datatype<CDT_event>(){return create_compound_dream_readout();}
219 template<> inline DataType create_datatype<VMM3_event>(){return create_compound_vmm3_readout();}
220 template<> inline DataType create_datatype<BM0_event>(){return create_compound_bm0_readout();}
221 template<> inline DataType create_datatype<BM2_event>(){return create_compound_bm2_readout();}
222 template<> inline DataType create_datatype<BMI_event>(){return create_compound_bmi_readout();}
223}
224
226inline HighFive::CompoundType hdf_compound_type(const ReadoutType readout) {
227 switch (readout) {
228 case ReadoutType::CAEN: return create_compound_caen_readout();
229 case ReadoutType::CDT: return create_compound_dream_readout();
230 case ReadoutType::VMM3: return create_compound_vmm3_readout();
231 case ReadoutType::BM0: return create_compound_bm0_readout();
232 case ReadoutType::BM2: return create_compound_bm2_readout();
233 case ReadoutType::BMI: return create_compound_bmi_readout();
234 default: throw std::runtime_error("Saving this readout type is not implemented yet!");
235 }
236}
237
239inline HighFive::DataType hdf5_type_for(const std::string& canonical_type) {
240 if (canonical_type == "int8_t") return HighFive::create_datatype<int8_t>();
241 if (canonical_type == "int16_t") return HighFive::create_datatype<int16_t>();
242 if (canonical_type == "int32_t") return HighFive::create_datatype<int32_t>();
243 if (canonical_type == "int64_t") return HighFive::create_datatype<int64_t>();
244 if (canonical_type == "uint8_t") return HighFive::create_datatype<uint8_t>();
245 if (canonical_type == "uint16_t") return HighFive::create_datatype<uint16_t>();
246 if (canonical_type == "uint32_t") return HighFive::create_datatype<uint32_t>();
247 if (canonical_type == "uint64_t") return HighFive::create_datatype<uint64_t>();
248 if (canonical_type == "float") return HighFive::create_datatype<float>();
249 if (canonical_type == "double") return HighFive::create_datatype<double>();
250 throw std::runtime_error("No HDF5 type mapping for: " + canonical_type);
251}
252
257inline HighFive::CompoundType build_hdf5_compound_type(const TypeSchema & schema) {
258 std::vector<HighFive::CompoundType::member_def> members;
259 members.reserve(schema.fields.size());
260
261 for (const auto& field : schema.fields) {
262 if (field.array_count > 0) {
263 throw std::runtime_error(
264 "build_hdf5_compound_type: array fields are not supported (field: " + field.name + ")"
265 );
266 }
267 members.push_back({field.name, hdf5_type_for(field.type), field.offset});
268 }
269
270 return HighFive::CompoundType(members, schema.total_size);
271}
Umbrella header for the C API used by the McStas components.
Parser for C struct type descriptions into a runtime type schema.
Minimal beam-monitor readout event: channel only.
Position-resolving beam-monitor readout event: channel, x, y.
Integrating beam-monitor readout event: channel, sum, 24-bit ADC.
CAEN readout event: group channel and amplitudes A-D.
CDT (DREAM-family) readout event: output module, cathode, anode.
Common fields of every stored readout event: routing (ring, FEN), time-of-flight, and the statistical...
Complete description of a parsed struct.
VMM3 readout event: BC, OTADC, GEO, TDC, VMM, channel.