actions
Loading...
Searching...
No Matches
sro_test_implementation.cc
Go to the documentation of this file.
1#include <gemc/gstreamer/sro/gSROImplementation.h>
2#include <gemc/gdynamicDigitization/gdynamicdigitization.h>
3
4#include <fstream>
5#include <thread>
6
7namespace {
8struct Data final : GSROData {
9 GSROEventId event;
10 std::size_t worker;
11 Data(GSROEventId id, std::size_t thread) : event(id), worker(thread) {}
12 std::size_t size_bytes() const noexcept override { return sizeof(*this); }
13};
14
15struct Timing final : GSROTiming {
16 std::optional<GSROTime> earliest_remaining_time(GSROEventId id) const override {
17 return GSROTime{static_cast<std::int64_t>(id) * 10};
18 }
19};
20
21struct Sink final : GSROFrameSink {
22 std::ofstream file;
23 const std::thread::id owner = std::this_thread::get_id();
24 explicit Sink(const std::string& filename) {
25 file.exceptions(std::ios::failbit | std::ios::badbit);
26 file.open(filename);
27 }
28 void write_frame(GSROFrame frame) override {
29 if (owner != std::this_thread::get_id()) { throw std::runtime_error("Wrong SRO output thread"); }
30 const auto& data = dynamic_cast<const Data&>(*frame.data);
31 file << "F " << data.event << ' ' << frame.frame_id << ' ' << frame.begin.count()
32 << ' ' << data.worker << '\n';
33 }
34 void finish_output() override { file.close(); }
35};
36
37struct Crate final : GSROCratePlugin {
38 GSROCrateId id;
39 std::vector<GSROPayload> pending;
40 Crate(GSROFrameSink& sink, GSROCrateId crate) : GSROCratePlugin(sink), id(crate) {}
41 void consume_payload(GSROPayload payload) override { pending.push_back(std::move(payload)); }
42 void advance_time(GSROTime boundary) override {
43 for (auto& payload : pending) {
44 if (payload.time >= boundary) { throw std::runtime_error("Unproven SRO payload released"); }
45 output.write_frame({id, payload.sequence, payload.time, payload.time + GSROTime{1},
46 std::move(payload.data)});
47 }
48 pending.clear();
49 }
50 void finish_run(const GSROEndContext& context) override {
51 pending.clear(); // This test implementation discards the unproven tail.
52 auto& sink = dynamic_cast<Sink&>(output);
53 sink.file << "E " << (context.reason == GSROEndReason::completed ? "completed" : "interrupted")
54 << ' ' << (context.safe_time ? context.safe_time->count() : -1) << '\n';
55 }
56};
57
58class Implementation final : public GSROImplementation {
59public:
61 GSROConfiguration configure_run(const GSRORunContext&) override {
62 GSROConfiguration config;
63 config.timing = std::make_shared<Timing>();
65 return config;
66 }
67 GSROCrateResources create_crate(GSROCrateId id, const GSRORunContext& run) const override {
68 auto sink = std::make_unique<Sink>(run.output_basename + "_r" + std::to_string(run.run_id) +
69 "_c" + std::to_string(id) + ".txt");
70 auto crate = std::make_unique<Crate>(*sink, id);
71 return {std::move(sink), std::move(crate)};
72 }
73};
74
75class Digitizer final : public GDynamicDigitization {
76public:
78 bool defineReadoutSpecsImpl() override { return true; } // Test hits are injected without step processing.
79 std::unique_ptr<GTrueInfoData> collectTrueInformationImpl(GHit*, std::size_t) override { return nullptr; }
80 void stream_hit(GHit*, std::size_t, const GSROEventContext& event, const GSROEmit& emit) const override {
81 if (gopts->getSwitch("sro_test_worker_failure")) {
82 throw std::runtime_error("synthetic SRO worker failure");
83 }
84 const auto worker = std::hash<std::thread::id>{}(std::this_thread::get_id());
85 for (GSROCrateId crate : {1u, 2u}) {
86 emit(crate, GSROTime{static_cast<std::int64_t>(event.event_id) * 10},
87 std::make_unique<Data>(event.event_id, worker));
88 }
89 }
90};
91} // namespace
92
93extern "C" GSROImplementation* GSROImplementationFactory(const std::shared_ptr<GOptions>& options) {
94 return new Implementation(options);
95}
96extern "C" GDynamicDigitization* GDynamicDigitizationFactory(const std::shared_ptr<GOptions>& options) {
97 return new Digitizer(options);
98}
GDynamicDigitization(const std::shared_ptr< GOptions > &g)
GSROImplementation(const std::shared_ptr< GOptions > &opts)
std::chrono::duration< std::int64_t, std::nano > GSROTime
std::uint32_t GSROCrateId
std::uint64_t GSROEventId
frame
run
event
GDynamicDigitization * GDynamicDigitizationFactory(const std::shared_ptr< GOptions > &options)
GSROImplementation * GSROImplementationFactory(const std::shared_ptr< GOptions > &options)
GSROCrateLimits crate_limits
std::shared_ptr< const GSROTiming > timing
std::size_t queue_messages
std::optional< GSROTime > safe_time
GSROEndReason reason
GSROTime time
std::uint64_t sequence
std::unique_ptr< const GSROData > data