R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BDigitizingEngine.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14#pragma once
15
17#include "R3BDigitizingPaddle.h"
18#include "R3BShared.h"
19#include <algorithm>
20#include <atomic>
21#include <cmath>
22#include <functional>
23#include <memory>
24#include <range/v3/algorithm/find_if.hpp>
25#include <range/v3/view/take.hpp>
26#include <range/v3/view/transform.hpp>
27#include <type_traits>
28#include <utility>
29#include <vector>
30
31namespace R3B::Digitizing
32{
34 {
35 public:
37 EngineInterface() = default;
38
40 virtual ~EngineInterface() = default;
41
43 EngineInterface(const EngineInterface& other) = delete;
45 auto operator=(const EngineInterface& other) -> EngineInterface& = delete;
49 auto operator=(EngineInterface&& other) -> EngineInterface& = delete;
50
62 void DepositLight(int paddle_id, double time, double energy_dep, double dist)
63 {
64 auto& paddle = add_paddle(paddle_id);
65 paddle.DepositLight({ time, energy_dep, dist });
66 }
67
73 [[nodiscard]] auto GetTriggerTime() const -> double;
74
82 void Init(int initial_capacity = 1);
83
89 void Reset()
90 {
91 ExtraReset();
92 size_ = 0;
93 }
94
102 void Construct();
103
110 [[nodiscard]] auto get_capacity() const { return paddles_.size(); };
111
131 template <typename Unary>
132 void DoEachPaddle(Unary fnt) const
133 {
134 for (const auto& paddle : ranges::views::take(paddles_, size_))
135 {
136 fnt(*paddle);
137 }
138 }
139
163 template <typename Unary>
164 auto DoAllPaddles(Unary fnt) const
165 {
166 return fnt(ranges::views::take(paddles_, size_) |
167 ranges::views::transform([](auto& paddle) -> const AbstractPaddle& { return *paddle; }));
168 }
169
170 private:
171 std::atomic<int> size_ = 0;
172 std::vector<std::unique_ptr<AbstractPaddle>>
174
175 [[nodiscard]] virtual auto make_new_paddle() const -> std::unique_ptr<AbstractPaddle> = 0;
176 virtual void ExtraInit(int initial_capacity) {}
177 virtual void ExtraReset() {}
178
184 void reserve_additional_paddles(int num);
185 auto add_paddle(int paddle_id) -> AbstractPaddle&;
186 };
187
188 // factory classes for paddle and channel:
189 template <typename ChannelClass, typename = std::enable_if_t<std::is_base_of_v<AbstractChannel, ChannelClass>>>
191 {
192 template <typename... Args>
193 explicit UseChannel(const Args&... args)
194 : BuildChannel([=](Side side) { return std::make_unique<ChannelClass>(side, args...); })
195 {
196 }
197 std::function<std::unique_ptr<ChannelClass>(Side)> BuildChannel;
198 };
199
200 template <typename PaddleClass, typename = std::enable_if_t<std::is_base_of_v<AbstractPaddle, PaddleClass>>>
202 {
203 template <typename... Args>
204 explicit UsePaddle(const Args&... args)
205 : BuildPaddle([=](int paddleID) { return std::make_unique<PaddleClass>(paddleID, args...); })
206 {
207 }
208 std::function<std::unique_ptr<PaddleClass>(int)> BuildPaddle;
209 };
210
211 template <typename PaddleClass, typename ChannelClass, typename InitFunc = std::function<void()>>
212 class Engine : public EngineInterface
213 {
214 public:
216 const UsePaddle<PaddleClass>& p_paddleClass,
217 const UseChannel<ChannelClass>& p_channelClass,
218 InitFunc initFunc = []() {})
219 : paddleClass_{ p_paddleClass }
220 , channelClass_{ p_channelClass }
222 , initFunc_{ initFunc }
223 {
224 }
225
233 void SetInit(const InitFunc& initFunc) { initFunc_ = initFunc; }
234 void ExtraReset() override {}
235
236 private:
239 InitFunc initFunc_;
240
241 void ExtraInit(int /*initial_capacity*/) override { initFunc_(); }
242 [[nodiscard]] auto make_new_paddle() const -> std::unique_ptr<AbstractPaddle> override
243 {
244 auto new_paddle = paddleClass_.BuildPaddle(-1);
245 new_paddle->SetChannel(channelClass_.BuildChannel(R3B::Side::left));
246 new_paddle->SetChannel(channelClass_.BuildChannel(R3B::Side::right));
247 return new_paddle;
248 }
249 };
250
251 // helper to create owning digitizingEngine:
252 template <typename... Args>
253 [[nodiscard]] auto CreateEngine(Args&&... args) -> std::unique_ptr<decltype(Engine{ std::forward<Args>(args)... })>
254 {
255 return std::make_unique<decltype(Engine{ std::forward<Args>(args)... })>(std::forward<Args>(args)...);
256 }
257
258} // namespace R3B::Digitizing
UseChannel< ChannelClass > channelClass_
Channel class factory.
Engine(const UsePaddle< PaddleClass > &p_paddleClass, const UseChannel< ChannelClass > &p_channelClass, InitFunc initFunc=[]() {})
auto make_new_paddle() const -> std::unique_ptr< AbstractPaddle > override
void SetInit(const InitFunc &initFunc)
Initialize the underlying data.
UsePaddle< PaddleClass > paddleClass_
Paddle class factory.
void reserve_additional_paddles(int num)
Reserve memories for additional number of paddles.
EngineInterface()=default
Default constructor.
auto operator=(const EngineInterface &other) -> EngineInterface &=delete
Copy assignment operator.
auto DoAllPaddles(Unary fnt) const
Accessor operator for all paddles stored in the current event.
auto operator=(EngineInterface &&other) -> EngineInterface &=delete
Move assignment operator.
virtual void ExtraInit(int initial_capacity)
EngineInterface(EngineInterface &&other)=delete
Move constructor.
void Init(int initial_capacity=1)
Initialization of the engine class.
EngineInterface(const EngineInterface &other)=delete
Copy constructor.
void Reset()
Reset the engine for a new event.
void Construct()
Construct singals from the paddles and channels.
virtual auto make_new_paddle() const -> std::unique_ptr< AbstractPaddle >=0
auto GetTriggerTime() const -> double
Get the trigger time of the current event.
auto add_paddle(int paddle_id) -> AbstractPaddle &
void DoEachPaddle(Unary fnt) const
Accessor operator for each paddle stored in the current event.
void DepositLight(int paddle_id, double time, double energy_dep, double dist)
Takes in a light deposition and pass it to the paddle.
std::vector< std::unique_ptr< AbstractPaddle > > paddles_
main data. This vector should rarely grow in the event loop!
virtual ~EngineInterface()=default
virtual destructor
std::atomic< int > size_
size of bars with valid signals in the current event
auto get_capacity() const
The number of preallocated bar objects in the engine.
NeuLAND digitizing finder task.
auto CreateEngine(Args &&... args) -> std::unique_ptr< decltype(Engine{ std::forward< Args >(args)... })>
UseChannel(const Args &... args)
std::function< std::unique_ptr< Type >(Side)> BuildChannel
std::function< std::unique_ptr< Type >(int)> BuildPaddle
UsePaddle(const Args &... args)