McStas Readout Master 0.3.3
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
33class Readout {
34public:
35 Readout(
36 std::string IpAddress,
37 const int UDPPort,
38 const int TCPPort,
39 const int Type=0x34,
40 efu_time p = efu_time(1),
41 efu_time t = efu_time()
42 ): Type(detectorType_from_int(Type)),
43 ipaddr(std::move(IpAddress)),
44 port(UDPPort),
45 tcp_port(TCPPort),
46 period(p),
47 time(t),
48 sender{ipaddr, static_cast<uint16_t>(UDPPort)}
49 {
50// sockOpen(ipaddr, port);
51 hp = (PacketHeaderV0*)&buffer[0];
52 auto prev = time - period;
53 setPulseTime(time.high(), time.low(), prev.high(), prev.low());
54 newPacket();
55 }
56
57 ~Readout() {
58 // ensure any buffered data is sent before the object is destroyed
59 send();
60 }
61
65 void addReadout(uint8_t Ring, uint8_t FEN, double tof, double weight, const void * data);
67 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const void * data);
68 // Specializations for handled data types
69 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const CAEN_readout_t * data);
70 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const TTLMonitor_readout_t * data);
71 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const CDT_readout_t * data);
72 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const VMM3_readout_t * data);
73 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BM0_readout_t * data);
74 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BM2_readout_t * data);
75 void addReadout(uint8_t Ring, uint8_t FEN, efu_time t, const BMI_readout_t * data);
76
78 int send();
79
81 void setPulseTime(uint32_t PHI, uint32_t PLO, uint32_t PPHI, uint32_t PPLO);
82
87 auto now = efu_time();
88 if ((now - time) >= &period){
89 now = time + period * ((now - time) / period);
90 }
91 // The ESS Caen EFUs require (now - prev) <= 5 * rep; so we should fake it
92 if ((now - time) > (period * 5u)) {
93 time = now - period;
94 }
95 send();
96 setPulseTime(now.high(), now.low(), time.high(), time.low());
97 newPacket();
98 time = now;
99 }
100
101 // Query the current pulse and previous pulse times
102 [[nodiscard]] std::pair<uint32_t, uint32_t> lastPulseTime() const;
103 [[nodiscard]] std::pair<uint32_t, uint32_t> prevPulseTime() const;
104 [[nodiscard]] std::pair<uint32_t, uint32_t> lastEventTime() const;
105
107 void newPacket();
108
110 int command_shutdown() const;
111
113 int verbose(const Verbosity v){
114 switch (v) {
115 case Verbosity::details: verbosity=3; break;
116 case Verbosity::info: verbosity=2; break;
117 case Verbosity::warnings: verbosity=1; break;
118 case Verbosity::errors: verbosity=0; break;
119 case Verbosity::silent: verbosity=-1; break;
120 default: verbosity=0;
121 }
122 return verbosity;
123 }
124 int verbose(const int v){verbosity = v; return verbosity;}
125
127 void dump_to(const std::string & filename, const std::string & dataset_name = "events");
128
129 void enable_network() {network = true;}
130 void disable_network() {network = false;}
131
132 void set_random_seed(const uint32_t seed) {
133 random_engine.seed(seed);
134 }
135
136 int random_poisson(const double mean) {
137 std::poisson_distribution<int> distribution(mean);
138 return distribution(random_engine);
139 }
140
141private:
142 HighFive::CompoundType datatype() const {
143 return ::hdf_compound_type(readoutType_from_detectorType(Type));
144 }
145
146 void check_size_and_send();
147
148 // Packet header
149 uint32_t phi{0}; // pulse and prev pulse high and low
150 uint32_t plo{0};
151 uint32_t pphi{0};
152 uint32_t pplo{0};
153
154 uint32_t lasthi{0};
155 uint32_t lastlo{0};
156
157 int SeqNum{0};
158 int OutputQueue{0};
159 DetectorType Type;
160
161 // TX Buffer
162 PacketHeaderV0 *hp{};
163 char buffer[9000]{};
164 const int MaxDataSize{8950};
165 int DataSize{0};
166 // IP and port number
167 std::string ipaddr;
168 int port{9000};
169 int tcp_port{8888};
170 int verbosity{0};
171
172 std::optional<Writer> writer{std::nullopt};
173 bool network{true};
174 efu_time period, time;
175 cluon::UDPSender sender;
176
177 std::mt19937 random_engine{std::default_random_engine{}()};
178};
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.
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 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).
int send()
Transmit the current data buffer.
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