McStas Readout Master 0.8.0
Loading...
Searching...
No Matches
ReadoutClass.h
Go to the documentation of this file.
1// Copyright (C) 2022 European Spallation Source, ERIC. See LICENSE file
2//===----------------------------------------------------------------------===//
7//===----------------------------------------------------------------------===//
8#pragma once
9
10#include "cluon-complete.hpp"
11
12#include <string>
13#include <utility>
14#include <optional>
15#include <random>
16
17#include "Structs.h"
18#include "Readout.h"
19#include "enums.h"
20#include "hdf_interface.h"
21#include "version.hpp"
22#include "efu_time.h"
23#include "writer.h"
24
36class RL_API Readout {
37public:
38 Readout(
39 std::string IpAddress,
40 const int UDPPort,
41 const int TCPPort,
42 const int Type,
43 const pulse_grid grid
44 ): Type(detectorType_from_int(Type)),
45 ipaddr(std::move(IpAddress)),
46 port(UDPPort),
47 tcp_port(TCPPort),
48 grid(grid),
49 period(grid.period()),
50 sender{ipaddr, static_cast<uint16_t>(UDPPort)}
51 {
52// sockOpen(ipaddr, port);
53 hp = (PacketHeaderV0*)&buffer[0];
54 set_pulse(grid.at_or_before(efu_time::now_nanoseconds()));
55 newPacket();
56 }
57
58 Readout(
59 std::string IpAddress,
60 const int UDPPort,
61 const int TCPPort,
62 const int Type=0x34,
63 const efu_time p = efu_time(1)
64 ): Readout(std::move(IpAddress), UDPPort, TCPPort, Type, pulse_grid::from_period(p)) {}
65
66 ~Readout() {
67 // ensure any buffered data is sent before the object is destroyed
68 send();
69 report_long_tof();
70 }
71
75 void addReadout(uint8_t Ring, uint8_t FEN, double tof, double weight, const void * data);
77 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const void * data);
78 // Specializations for handled data types
79 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const CAEN_readout_t * data);
80 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const CDT_readout_t * data);
81 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const VMM3_readout_t * data);
82 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BM0_readout_t * data);
83 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BM2_readout_t * data);
84 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BMI_readout_t * data);
85
87 int send();
88
90 void setPulseTime(uint32_t PHI, uint32_t PLO, uint32_t PPHI, uint32_t PPLO);
91
96 send();
97 // the latest pulse on the grid; the previous one a period before it, as for a
98 // continuously pulsed source (the CAEN EFUs reject a gap of more than five)
99 set_pulse(grid.at_or_before(efu_time::now_nanoseconds()));
100 newPacket();
101 }
102
103 // Query the current pulse and previous pulse times
104 [[nodiscard]] std::pair<uint32_t, uint32_t> lastPulseTime() const;
105 [[nodiscard]] std::pair<uint32_t, uint32_t> prevPulseTime() const;
106 [[nodiscard]] std::pair<uint32_t, uint32_t> lastEventTime() const;
107
109 void newPacket();
110
112 int command_shutdown() const;
113
115 int verbose(const Verbosity v){
116 switch (v) {
117 case Verbosity::details: verbosity=3; break;
118 case Verbosity::info: verbosity=2; break;
119 case Verbosity::warnings: verbosity=1; break;
120 case Verbosity::errors: verbosity=0; break;
121 case Verbosity::silent: verbosity=-1; break;
122 default: verbosity=0;
123 }
124 return verbosity;
125 }
126 int verbose(const int v){verbosity = v; return verbosity;}
127
129 void dump_to(const std::string & filename, const std::string & dataset_name = "events");
130
135 void fold_tof(const bool fold) { fold_tof_ = fold; }
137 [[nodiscard]] uint64_t long_tof_count() const { return long_tof_; }
138
141 void output_queue(const int queue) {
142 OutputQueue = queue;
143 hp->OutputQueue = static_cast<uint8_t>(queue);
144 }
145 [[nodiscard]] int output_queue() const { return OutputQueue; }
147 [[nodiscard]] int sequence_number() const { return SeqNum; }
148
149 void enable_network() {network = true;}
150 void disable_network() {network = false;}
151
152 void set_random_seed(const uint32_t seed) {
153 random_engine.seed(seed);
154 }
155
156 int random_poisson(const double mean) {
157 std::poisson_distribution<int> distribution(mean);
158 return distribution(random_engine);
159 }
160
161private:
162 HighFive::CompoundType datatype() const {
163 return ::hdf_compound_type(readoutType_from_detectorType(Type));
164 }
165
166 void check_size_and_send();
167
168 // Packet header
169 uint32_t phi{0}; // pulse and prev pulse high and low
170 uint32_t plo{0};
171 uint32_t pphi{0};
172 uint32_t pplo{0};
173
174 uint32_t lasthi{0};
175 uint32_t lastlo{0};
176
177 int SeqNum{0};
178 int OutputQueue{0};
179 DetectorType Type;
180
181 // TX Buffer
182 PacketHeaderV0 *hp{};
183 char buffer[9000]{};
184 const int MaxDataSize{8950};
185 int DataSize{0};
186 // IP and port number
187 std::string ipaddr;
188 int port{9000};
189 int tcp_port{8888};
190 int verbosity{0};
191
192 std::optional<Writer> writer{std::nullopt};
193 bool network{true};
194 bool fold_tof_{false};
195 uint64_t long_tof_{0};
196 void report_long_tof() const;
197 pulse_grid grid;
198 efu_time period, time;
199 cluon::UDPSender sender;
200
202 void set_pulse(const uint64_t ns) {
204 const auto prev = efu_time::from_nanoseconds(ns - grid.period_ns());
205 setPulseTime(time.high(), time.low(), prev.high(), prev.low());
206 }
207
208 std::mt19937 random_engine{std::default_random_engine{}()};
209};
Umbrella header for the C API used by the McStas components.
ESS and Bifrost readout data structures.
Runtime-streaming readout generator used by the legacy Readout components.
void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const void *data)
Add a single readout with an explicit event time.
void output_queue(const int queue)
Send on this output queue (0 until set). An EFU keeps one packet sequence per queue,...
int command_shutdown() const
Tell the remote EFU to shut down via its TCP command port.
void newPacket()
Initialize a new packet with no readouts.
void fold_tof(const bool fold)
Choose whether add-by-time-of-flight readouts are stamped at pulse + (tof % period) — attributing eac...
void addReadout(uint8_t Ring, uint8_t FEN, double tof, double weight, const void *data)
Add a weighted readout: draws n ~ Poisson(weight) and buffers the event n times (weight <= 0 is a noi...
void update_time()
Advance the reference (pulse) time to now, flushing the buffer and starting a new packet; keeps (now ...
void setPulseTime(uint32_t PHI, uint32_t PLO, uint32_t PPHI, uint32_t PPLO)
Update the pulse and previous pulse times (high/low pairs).
void dump_to(const std::string &filename, const std::string &dataset_name="events")
Also store every added readout to a legacy flat HDF5 file (see Writer).
uint64_t long_tof_count() const
How many readouts so far had a time-of-flight of at least one pulse period.
int send()
Transmit the current data buffer.
int sequence_number() const
The number the next packet will be sent with.
int verbose(const Verbosity v)
Set verbosity via enum.
ESS EFU two-integer timestamp: whole seconds since the UNIX epoch plus ticks of the 88....
Definition efu_time.h:19
static efu_time from_nanoseconds(const uint64_t ns)
Nanoseconds since the UNIX epoch, to the nearest tick.
Definition efu_time.h:120
static uint64_t now_nanoseconds()
The system clock, in nanoseconds since the UNIX epoch.
Definition efu_time.h:132
The source's pulses: pulse k is at k periods after the UNIX epoch.
Definition efu_time.h:177
static pulse_grid from_period(const efu_time &period)
For a period given as a time: to the nearest nanosecond. efu_time(double) truncates to a whole tick,...
Definition efu_time.h:190
uint64_t at_or_before(const uint64_t ns) const
The latest pulse at or before ns.
Definition efu_time.h:197