R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BDigitizingTamex.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
22
24#include "R3BDigitizingPaddle.h"
25#include "R3BShared.h"
26#include "TRandom3.h"
28#include <algorithm>
29#include <cstdint>
30#include <cstdlib>
31#include <functional>
32#include <vector>
33
36
38{
39 class Channel;
40 struct Params
41 {
42 // NOLINTBEGIN
44 double pmt_thresh = 1.;
45 double saturation_coefficient = 0.012;
46 double time_res = 0.15;
47 double energy_res_rel = 0.05;
48 double energy_gain = 15.0;
49 double pedestal = 14.0;
50 double max_time = 1000.;
51 double min_time = 1.;
52 double pileup_time_window = 1000.;
53 double pileup_distance = 100.;
54 double min_energy = 0.067;
55 std::reference_wrapper<TRandom3> rnd_gen;
56 // NOLINTEND
57
58 explicit Params(TRandom3&);
59 };
60
61 enum class PeakPileUpStrategy : uint8_t
62 {
66 };
67
68 class PMTPeak
69 {
70 public:
71 PMTPeak() = default;
73 auto operator<(const PMTPeak& rhs) const -> bool { return (time_ < rhs.time_); }
74 auto operator==(const PMTPeak& rhs) const -> bool { return std::abs(time_ - rhs.time_) < peakWidth; }
75 auto operator+=(const PMTPeak& other) -> PMTPeak&;
76 [[nodiscard]] auto GetHeight() const -> double { return height_; }
77 [[nodiscard]] auto GetLETime() const -> double { return time_; }
78 static constexpr double peakWidth = 15.0; // ns
79
80 private:
81 double height_ = 0.0;
82 double time_ = 0.0;
83 };
84
85 class FQTPeak
86 {
87 public:
88 FQTPeak(const PMTPeak& pmtPeak, Channel* channel);
89 FQTPeak() = default;
90
91 // Getters:
92 [[nodiscard]] auto GetToT() const -> double { return time_over_thresh_; }
93 [[nodiscard]] auto GetEnergy() const -> double { return energy_; }
94 [[nodiscard]] auto GetLETime() const -> double { return leading_edge_time_; }
95 [[nodiscard]] auto GetTETime() const -> double { return trailing_edge_time_; }
96
97 auto operator==(const FQTPeak& other) const -> bool;
98 void operator+=(const FQTPeak& other);
99 auto operator-(const FQTPeak& other) const -> double { return leading_edge_time_ - other.leading_edge_time_; }
100 auto operator-(double time) const -> double { return leading_edge_time_ - time; };
101 auto operator>(const FQTPeak& other) const -> bool { return leading_edge_time_ - other.leading_edge_time_ > 0; }
102 auto operator<(const FQTPeak& other) const -> bool { return leading_edge_time_ - other.leading_edge_time_ < 0; }
103
104 void AddEnergy(double energy) { energy_ += energy; }
105
106 static auto ToT2Energy(double width, const Params& par) -> double
107 {
108 return std::max(1., width - par.pedestal) / par.energy_gain;
109 }
110
111 static auto Energy2ToT(double height, const Params& par) -> double
112 {
113 auto time_over_thresh = 0.0;
114 if (height > par.min_energy)
115 {
116 time_over_thresh = height * par.energy_gain + par.pedestal;
117 }
118 else
119 {
120 time_over_thresh = height * par.energy_gain * (par.pedestal + 1);
121 }
122 return time_over_thresh;
123 }
124 explicit operator Digitizing::AbstractChannel::Hit() const;
125
126 private:
127 double time_over_thresh_ = 0.0; //<! The temperal time-over-thresh of the TmxPeak in [ns]
128 double energy_ = 0.0; //<! The energy value of the FQT signal [MeV] (without threshold)
129 double leading_edge_time_ = 0.0; //<! Leading edge of the TmxPeak in [ns]
130 double trailing_edge_time_ = 0.0; //<! Tailing edge of the TmxPeak
131 Channel* channel_ptr_ = nullptr; //<! Pointer to the channel which the peak belongs to
132 };
133
135 {
136 public:
137 Channel(Side, PeakPileUpStrategy strategy, TRandom3&);
139 PeakPileUpStrategy strategy,
140 const Params&,
141 R3B::Neuland::Cal2HitPar* cal_to_hit_par = nullptr,
142 bool has_cal_output = false);
144 : Channel(side, strategy, GetDefaultRandomGen())
145 {
146 }
147 // Setters:
149 void SetPar(const Tamex::Params& par) { par_ = par; }
150
151 // Getters:
152 [[nodiscard]] auto GetPar() const -> const Tamex::Params& { return par_; }
153 [[nodiscard]] auto GetFQTPeaks() const -> const std::vector<FQTPeak>& { return fqt_peaks_; }
154 [[nodiscard]] auto GetPMTPeaks() const -> const std::vector<PMTPeak>& { return pmt_peaks_; }
155 auto GetCal2HitPar() -> auto* { return neuland_hit_par_; }
156
157 void add_signal(Signal /*signal*/) override;
158 [[nodiscard]] auto CreateHit(const FQTPeak& peak) const -> Hit;
159 [[nodiscard]] auto CreateCalSignal(const FQTPeak& peak) const -> CalSignal;
160
161 private:
163 std::vector<PMTPeak> pmt_peaks_;
164 std::vector<FQTPeak> fqt_peaks_;
167
168 // private virtual functions
169 void construct_hits(Hits& hits) override;
170 void construct_cal_signals(CalSignals& cal_signals) const override;
171 void extra_reset() override;
172 void pre_construct() override;
173
174 // private non-virtual functions
175 void set_hit_module_par(int PaddleId);
176 [[nodiscard]] auto check_paddle_id_in_hit_par() const -> bool;
177 [[nodiscard]] auto smear_energy(double) const -> double;
178 [[nodiscard]] auto smear_time(double) const -> double;
179 [[nodiscard]] auto to_unsat_energy(double) const -> double;
180 [[nodiscard]] auto calculate_ToT(double energy) const -> double;
181 template <typename Peak>
182 void apply_threshold(/* inout */ std::vector<Peak>&);
183 void construct_FQT_peaks(std::vector<FQTPeak>& FQTPeaks, std::vector<PMTPeak>& pmtPeaks);
184 template <typename Peak>
185 static void do_peak_pileup(/* inout */ std::vector<Peak>& peaks);
186
187 static void peak_pileup_with_distance(/* inout */ std::vector<FQTPeak>& peaks, double distance);
188 static void peak_pileup_in_time_window(/* inout */ std::vector<FQTPeak>& peaks, double time_window);
189 void fqt_peak_pileup(/* inout */ std::vector<FQTPeak>& peaks);
190 };
191
192} // namespace R3B::Digitizing::Neuland::Tamex
std::vector< CalSignal > CalSignals
static auto GetDefaultRandomGen() -> TRandom3 &
void SetPar(const Tamex::Params &par)
void SetPileUpStrategy(PeakPileUpStrategy strategy)
auto GetPar() const -> const Tamex::Params &
static void do_peak_pileup(std::vector< Peak > &peaks)
void construct_cal_signals(CalSignals &cal_signals) const override
auto calculate_ToT(double energy) const -> double
auto GetPMTPeaks() const -> const std::vector< PMTPeak > &
auto CreateHit(const FQTPeak &peak) const -> Hit
static void peak_pileup_in_time_window(std::vector< FQTPeak > &peaks, double time_window)
auto GetFQTPeaks() const -> const std::vector< FQTPeak > &
void fqt_peak_pileup(std::vector< FQTPeak > &peaks)
Channel(Side side, PeakPileUpStrategy strategy=PeakPileUpStrategy::width)
static void peak_pileup_with_distance(std::vector< FQTPeak > &peaks, double distance)
auto CreateCalSignal(const FQTPeak &peak) const -> CalSignal
void construct_FQT_peaks(std::vector< FQTPeak > &FQTPeaks, std::vector< PMTPeak > &pmtPeaks)
Channel(Side, PeakPileUpStrategy strategy, TRandom3 &)
FQTPeak(const PMTPeak &pmtPeak, Channel *channel)
auto operator==(const FQTPeak &other) const -> bool
auto operator<(const FQTPeak &other) const -> bool
static auto Energy2ToT(double height, const Params &par) -> double
auto operator-(double time) const -> double
auto operator-(const FQTPeak &other) const -> double
auto operator>(const FQTPeak &other) const -> bool
static auto ToT2Energy(double width, const Params &par) -> double
auto operator+=(const PMTPeak &other) -> PMTPeak &
auto operator<(const PMTPeak &rhs) const -> bool
auto operator==(const PMTPeak &rhs) const -> bool
double energy_res_rel
Gaus(e, fEResRel * e) [].
double time_res
time + Gaus(0., fTimeRes) [ns]
double min_energy
minimal energy of a FQT peak [MeV]
double saturation_coefficient
Saturation coefficient of PMTs.
double pedestal
Energy offset parameter [ns].
bool experimental_data_is_corrected_for_saturation
Flag if saturation effect enabled.
std::reference_wrapper< TRandom3 > rnd_gen
Reference to shared random generator.