12#include "FairLogger.h"
13#include "FairRunSim.h"
17#include "TGeoManager.h"
18#include "TGeoNavigator.h"
22constexpr Float_t n_photons_min = 3.5f;
23constexpr Float_t n_photons_max = 104.0f;
24constexpr Float_t time_res = 150e-3f;
25constexpr Float_t signal_speed = 15.0f;
26const Float_t inv_signal_speed = 1.0f / signal_speed;
28constexpr Float_t light_attenuation_params[2] = {20., 300.};
29constexpr Float_t n_pixels_to_qdc_params[4] = {0.172, -1.31, 0.006,
32Float_t light_attenuation(Float_t distance) {
33 return TMath::Exp(-(distance - light_attenuation_params[0]) /
34 light_attenuation_params[1]);
37Float_t sipm_saturation(Float_t ly) {
38 Float_t factor = 1 - TMath::Exp(-ly / n_photons_max);
39 return n_photons_max * factor;
42Float_t n_pixels_to_qdc(Float_t npix) {
44 gRandom->Gaus(n_pixels_to_qdc_params[0], n_pixels_to_qdc_params[2]);
46 gRandom->Gaus(n_pixels_to_qdc_params[1], n_pixels_to_qdc_params[3]);
57 const std::vector<Float_t>& weights) {
59 dynamic_cast<MTCDetector*
>(gROOT->GetListOfGlobals()->FindObject(
"MTC"));
61 LOG(fatal) <<
"MTCDetHit: MTCDetector not found";
69 Float_t total_light_yield = 0.0f;
70 Float_t earliest_to_A = std::numeric_limits<Float_t>::max();
71 Float_t earliest_to_B = std::numeric_limits<Float_t>::max();
72 const size_t n = points.size();
73 Float_t signal_sum = 0.0f;
74 bool hit_flag =
false;
77 if (plane_type == 2) {
78 Float_t x_temp = 0.0, y_temp = 0.0, z_temp = 0.0;
79 for (
auto* pt : points) {
80 signal_sum += pt->GetEnergyLoss();
82 Float_t arrival = pt->GetTime();
83 earliest_to_B = std::min(earliest_to_B, arrival);
88 time = gRandom->Gaus(earliest_to_B, time_res);
99 total_light_yield = 0.0f;
101 TVector3 sipmA, sipmB;
102 MTCDet->GetSiPMPosition(SiPMChan, sipmA, sipmB);
107 for (
size_t i = 0; i < n; ++i) {
108 auto* pt = points[i];
109 Float_t energy = pt->GetEnergyLoss();
110 Float_t weight = weights[i];
111 Float_t signal = energy * weight;
114 TVector3 impact(pt->GetX(), pt->GetY(), pt->GetZ());
115 const Float_t distance = (sipmB - impact).Mag();
118 Float_t light_yield = signal * 1e6f * 0.16f;
119 light_yield *= light_attenuation(distance);
120 total_light_yield += light_yield;
123 Float_t arrival = pt->GetTime() + distance * inv_signal_speed;
124 earliest_to_A = std::min(earliest_to_A, arrival);
128 const Int_t smeared_light_yield = gRandom->Poisson(total_light_yield);
129 const Float_t n_pixels = sipm_saturation(smeared_light_yield);
130 signals = n_pixels_to_qdc(n_pixels);
133 hit_flag = (smeared_light_yield > n_photons_min);
135 time = gRandom->Gaus(earliest_to_A, time_res);
147 "MTCDetHit: Detector ID %d, Layer %d, Station Type %d, SiPM %d, Channel "
148 "%d, Signal %.2f, Time %.3f \n",
Int_t GetSiPMChan() const
Int_t GetStationType() const
Float_t GetEnergy() const
Int_t fDetectorID
Detector unique identifier.