16#include <FairRuntimeDb.h>
25#include <FairRunAna.h>
29#include <fairlogger/Logger.h>
39 auto CheckOverlapping(
const T& peak, std::vector<T>& peaks) ->
decltype(peaks.begin());
41 void ReOverlapping(
typename std::vector<T>::iterator v_iter, std::vector<T>& peaks);
43 void RemovePeakAt(
typename std::vector<T>::iterator v_iter, std::vector<T>& peaks);
45 void set_par_with_hit_module_par(Tamex::Params& par,
46 const R3B::Neuland::HitModulePar& module_par,
51 par.saturation_coefficient = module_par.
pmt_saturation.get(side).value;
52 par.energy_gain = module_par.
energy_gain.get(side).value;
53 par.pedestal = module_par.
pedestal.get(side).value;
55 par.min_energy = 1 / par.energy_gain;
70 :
time_(channel_signal.time)
72 const auto& par = channel.
GetPar();
91 LOG(fatal) <<
"channel is not bound to FQTPeak object!";
93 const auto& par = channel->
GetPar();
104 LOG(warn) <<
"the times of both PMT signals are 0!";
106 return (
leading_edge_time_ <= (other.leading_edge_time_ + other.time_over_thresh_)) &&
144 auto is_valid =
false;
151 R3BLOG(warn,
"Can't setup parameter in the root file correctly!.");
156 if (
GetPaddle()->GetPaddleID() > PaddleId_max)
158 LOG(warn) <<
"Paddle id " <<
GetPaddle()->GetPaddleID() <<
" exceeds the id " << PaddleId_max
159 <<
" in the parameter file!";
181 auto peakQdc = peak.GetEnergy();
182 auto peakTime = peak.GetLETime();
203 auto peak_energy = peak.GetEnergy();
204 auto peakTime = peak.GetLETime();
209 signal.tle = peakTime;
217 const auto& par =
GetPar();
218 return ((energy * par.energy_gain) + par.pedestal);
221 template <
typename Peak>
224 if (peaks.size() <= 1)
229 std::sort(peaks.begin(), peaks.end(), std::less{});
230 for (
auto front_peak = peaks.begin(); front_peak != peaks.end(); ++front_peak)
232 auto end_peak = std::remove_if(front_peak + 1,
234 [&front_peak](
auto& peak)
236 if (*front_peak == peak)
238 (*front_peak) += peak;
243 peaks.erase(end_peak, peaks.end());
253 std::sort(peaks.begin(), peaks.end(), std::less{});
255 for (
auto front_peak = peaks.begin(); front_peak != peaks.end(); ++front_peak)
257 auto last_leading_time = front_peak->GetLETime();
258 auto end_peak = std::remove_if(front_peak + 1,
262 if ((peak - last_leading_time) < distance)
264 front_peak->AddEnergy(peak.GetEnergy());
265 last_leading_time = peak.GetLETime();
270 peaks.erase(end_peak, peaks.end());
280 std::sort(peaks.begin(), peaks.end(), std::less{});
282 auto& front_peak = peaks.front();
283 std::for_each(peaks.begin() + 1,
287 if ((peak - front_peak) < time_window)
289 front_peak.AddEnergy(peak.GetEnergy());
292 peaks.erase(peaks.begin() + 1, peaks.end());
313 template <
typename Peak>
317 auto it_end = std::remove_if(peaks.begin(),
319 [
this](
const auto& peak) { return peak.GetHeight() < this->GetPar().pmt_thresh; });
320 peaks.erase(it_end, peaks.end());
325 FQTPeaks.reserve(pmtPeaks.size());
328 std::sort(pmtPeaks.begin(), pmtPeaks.end());
332 for (
auto const& peak : pmtPeaks)
334 FQTPeaks.emplace_back(peak,
this);
342 set_par_with_hit_module_par(
par_, module_par,
GetSide());
375 qdc =
par_.rnd_gen.get().Gaus(qdc,
par_.energy_res_rel * qdc);
384 if (
par_.experimental_data_is_corrected_for_saturation)
386 qdc = qdc / (1 -
par_.saturation_coefficient * qdc);
#define R3BLOG(severity, x)
ChannelCalSignal CalSignal
std::vector< CalSignal > CalSignals
AbstractChannel(R3B::Side side, bool has_cal_output=false)
auto GetSide() const -> R3B::Side
auto GetPaddle() const -> AbstractPaddle *
auto smear_energy(double) const -> double
auto GetPar() const -> const Tamex::Params &
auto smear_time(double) const -> double
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
void pre_construct() override
void construct_hits(Hits &hits) override
std::vector< FQTPeak > fqt_peaks_
auto to_unsat_energy(double) const -> double
auto CreateHit(const FQTPeak &peak) const -> Hit
PeakPileUpStrategy pileup_strategy_
void extra_reset() override
static void peak_pileup_in_time_window(std::vector< FQTPeak > &peaks, double time_window)
R3B::Neuland::Cal2HitPar * neuland_hit_par_
void add_signal(Signal) override
void fqt_peak_pileup(std::vector< FQTPeak > &peaks)
auto check_paddle_id_in_hit_par() const -> bool
static void peak_pileup_with_distance(std::vector< FQTPeak > &peaks, double distance)
void apply_threshold(std::vector< Peak > &)
auto CreateCalSignal(const FQTPeak &peak) const -> CalSignal
std::vector< PMTPeak > pmt_peaks_
void construct_FQT_peaks(std::vector< FQTPeak > &FQTPeaks, std::vector< PMTPeak > &pmtPeaks)
Channel(Side, PeakPileUpStrategy strategy, TRandom3 &)
FQTPeak(const PMTPeak &pmtPeak, Channel *channel)
double trailing_edge_time_
auto GetLETime() const -> double
auto operator==(const FQTPeak &other) const -> bool
static auto Energy2ToT(double height, const Params &par) -> double
void operator+=(const FQTPeak &other)
static auto ToT2Energy(double width, const Params &par) -> double
double leading_edge_time_
auto operator+=(const PMTPeak &other) -> PMTPeak &
const size_t TmxPeaksInitialCapacity
double time
Time value of the channel signal.
double intensity
Intensity of the channel signal.
std::reference_wrapper< TRandom3 > rnd_gen
Reference to shared random generator.
LRPair< ValueError< double > > pedestal
LRPair< ValueError< double > > pmt_threshold
LRPair< ValueError< double > > energy_gain
LRPair< ValueError< double > > pmt_saturation