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