R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BDigitizingPaddle.cxx
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#include "R3BDigitizingPaddle.h"
16#include "R3BShared.h"
17#include <algorithm>
18#include <fairlogger/Logger.h>
19#include <functional>
20#include <memory>
21#include <utility>
22#include <vector>
23
24namespace R3B::Digitizing
25{
27 : paddle_id_{ paddleID }
28 , signal_coupling_strategy_{ std::move(strategy) }
29 {
30 }
31
32 void AbstractPaddle::SetChannel(std::unique_ptr<AbstractChannel> channel)
33 {
34 channel->SetPaddle(this);
35 channel->AttachToPaddle(this);
36 if (channel->GetSide() == Side::left)
37 {
38 left_channel_ = std::move(channel);
39 }
40 else if (channel->GetSide() == Side::right)
41 {
42 right_channel_ = std::move(channel);
43 }
44 else
45 {
46 LOG(error) << "Channel side is invalid!";
47 }
48 }
49
51 {
52 if (side == Side::left)
53 {
54 return *left_channel_;
55 }
56 return *right_channel_;
57 }
58
60 {
61 auto channelHits = compute_channel_signals(signal);
62 left_channel_->AddSignal(channelHits.left);
63 right_channel_->AddSignal(channelHits.right);
64 }
65
66 auto AbstractPaddle::HasFired() const -> bool
67 {
68 if (left_channel_ == nullptr || right_channel_ == nullptr)
69 {
70 LOG(fatal) << "channels failed to be constructed when checking fire! ";
71 return false;
72 }
73 return (left_channel_->HasFired() && right_channel_->HasFired());
74 }
75
76 auto AbstractPaddle::HasHalfFired() const -> bool
77 {
78 return (left_channel_->HasFired() && !right_channel_->HasFired()) ||
79 (!left_channel_->HasFired() && right_channel_->HasFired());
80 }
81
83 const AbstractChannel::Hits& firstSignals,
84 const AbstractChannel::Hits& secondSignals) const
85 {
86 auto channelSignalPairs = signal_coupling_strategy_(*this, firstSignals, secondSignals);
87
88 auto paddleSignals = std::vector<Hit>();
89 paddleSignals.reserve(channelSignalPairs.size());
90
91 for (auto& it : channelSignalPairs)
92 {
93 // warning if two channel signals are from the same side
94 if (it.left.get().side == it.right.get().side)
95 {
96 LOG(warn) << "DigitizingEngine: ConstructPaddleSignals(): cannot construct the paddle signal from the "
97 "channels on the same side!";
98 }
99
100 // swap the channel signals if necessary
101 if (it.left.get().side != Side::left)
102 {
103 std::swap(it.left, it.right);
104 }
105 auto paddleSignal = Hit{ LRPair{ &(it.left.get()), &(it.right.get()) } };
106
107 paddleSignal.energy = compute_energy(it.left, it.right);
108 paddleSignal.time = compute_time(it.left, it.right);
109 paddleSignal.position = compute_position(it.left, it.right);
110 paddle_signals.push_back(paddleSignal);
111 }
112 }
113
115 {
116 signal_hits_.clear();
118 left_channel_->Construct();
119 right_channel_->Construct();
120 if (HasFired())
121 {
123 }
124 }
125
127 {
128 signal_hits_.clear();
129 left_channel_->Reset();
130 right_channel_->Reset();
131 paddle_id_ = -1;
132 }
133
135 const AbstractChannel::Hits& firstSignals,
136 const AbstractChannel::Hits& secondSignals)
137 -> std::vector<ChannelSignalPair>
138 {
139 auto firstSignalRefs =
140 std::vector<std::reference_wrapper<const AbstractChannel::Hit>>(firstSignals.begin(), firstSignals.end());
141 auto secondSignalRefs =
142 std::vector<std::reference_wrapper<const AbstractChannel::Hit>>(secondSignals.begin(), secondSignals.end());
143 auto channelSignalPairs = std::vector<ChannelSignalPair>{};
144 channelSignalPairs.reserve(std::min(firstSignals.size(), secondSignals.size()));
145
146 auto sortSignalByTime = [](auto signals)
147 {
148 std::sort(signals.begin(),
149 signals.end(),
150 [](auto& first, auto& second) { return first.get().tdc < second.get().tdc; });
151 };
152 sortSignalByTime(firstSignalRefs);
153 sortSignalByTime(secondSignalRefs);
154
155 for (auto first_it = firstSignalRefs.begin(), second_it = secondSignalRefs.begin();
156 first_it < firstSignalRefs.end() && second_it < secondSignalRefs.end();
157 ++first_it, ++second_it)
158 {
159 channelSignalPairs.emplace_back(*first_it, *second_it);
160 }
161 return channelSignalPairs;
162 }
163
164 auto AbstractPaddle::GetTrigTime() const -> double
165 {
166 return std::min(right_channel_->GetTrigTime(), left_channel_->GetTrigTime());
167 }
168
169} // namespace R3B::Digitizing
virtual auto compute_energy(const AbstractChannel::Hit &firstSignal, const AbstractChannel::Hit &secondSignal) const -> double=0
virtual auto compute_position(const AbstractChannel::Hit &rightSignal, const AbstractChannel::Hit &leftSignal) const -> double=0
virtual auto compute_channel_signals(const Signal &hit) const -> Pair< AbstractChannel::Signal >=0
std::unique_ptr< AbstractChannel > left_channel_
void construct_paddle_signals(Hits &paddle_signals, const AbstractChannel::Hits &firstSignals, const AbstractChannel::Hits &secondSignals) const
std::unique_ptr< AbstractChannel > right_channel_
std::function< std::vector< ChannelSignalPair >(const AbstractPaddle &, const AbstractChannel::Hits &, const AbstractChannel::Hits &)> SignalCouplingStrategy
void DepositLight(const Signal &signal)
virtual auto compute_time(const AbstractChannel::Hit &firstSignal, const AbstractChannel::Hit &secondSignal) const -> double=0
void SetChannel(std::unique_ptr< AbstractChannel > channel)
static auto SignalCouplingByTime(const AbstractPaddle &self, const AbstractChannel::Hits &firstSignals, const AbstractChannel::Hits &secondSignals) -> std::vector< ChannelSignalPair >
auto GetChannel(R3B::Side side) const -> const Digitizing::AbstractChannel &
SignalCouplingStrategy signal_coupling_strategy_
AbstractPaddle(int paddleID, SignalCouplingStrategy strategy=SignalCouplingByTime)