ATLAS Offline Software
Loading...
Searching...
No Matches
HGTD_TimeResolutionTool.cxx
Go to the documentation of this file.
1
8
10
11#include <algorithm>
12#include <cmath>
13
14#include "AthenaKernel/Units.h"
15#include "GaudiKernel/SystemOfUnits.h"
16#include "Math/Polynomial.h"
17
19 const std::string &name,
20 const IInterface *parent)
21 : AthAlgTool(type, name, parent) {}
22
24 const double depositedCharge, const double radius,
25 const double integratedLumi) const {
26
27 const double receivedFluence{sensorFluence(
28 replacementCorrectedLuminosity(integratedLumi, radius), radius)};
29
30 // Multiple processes contribute to the total time resolution. They are added
31 // here in quadrature one-by-one.
32 double timeResVariance{0.0};
33 timeResVariance += std::pow(sigmaLandau(receivedFluence), 2.0);
34 timeResVariance +=
35 std::pow(sigmaALTIROCJitter(depositedCharge, receivedFluence), 2.0);
36 timeResVariance += std::pow(sigmaTDC(), 2.0);
37 timeResVariance += std::pow(sigmaClock(), 2.0);
38
39 return std::sqrt(timeResVariance);
40}
41
43 const double integratedLumi, const double radius) const {
44
45 constexpr double innerRingRadius{230.0 * Athena::Units::mm};
46 constexpr double middleRingRadius{470.0 * Athena::Units::mm};
47
48 const std::vector<double> innerRingReplacementLumis{
49 // Unit is fb^-1
50 1000.0,
51 2000.0,
52 3000.0,
53 };
54
55 const std::vector<double> middleRingReplacementLumis{
56 // Unit is fb^-1
57 2000.0,
58 };
59
60 double replacementLumi{0.0};
61
62 if (radius < innerRingRadius) {
63 replacementLumi =
64 latestReplacementLuminosity(integratedLumi, innerRingReplacementLumis);
65 } else if (radius < middleRingRadius) {
66 replacementLumi =
67 latestReplacementLuminosity(integratedLumi, middleRingReplacementLumis);
68 }
69 // Outer ring does not have replacements - replacement lumi is 0.0
70
71 return integratedLumi - replacementLumi;
72}
73
75 const double integratedLumi,
76 const std::vector<double> &replacementLumis) const {
77
78 auto it = std::lower_bound(replacementLumis.begin(), replacementLumis.end(),
79 integratedLumi);
80
81 return it == replacementLumis.begin() ? 0.0 : *(--it);
82}
83
85 const double sensorAccumulatedLumi, const double radius) const {
86
87 // Maximum luminosity expected by sensors in fb^-1
88 constexpr double maxSensorLuminosity{4000.0};
89
90 // 4th order polynomial parametrization of the neutron fluence as function of
91 // radius in cm.
92 ROOT::Math::Polynomial neutral(2.82428e+08, -5.22843e+10, 3.62182e+12,
93 -1.4085e+14, 4.08821e+15);
94
95 // Equivalent as line above, but for charged hadrons.
96 ROOT::Math::Polynomial charged(1.03139e+09, -2.06558e+11, 1.53897e+13,
97 -5.18627e+14, 7.17046e+15);
98
99 return (neutral(radius / Athena::Units::cm) +
100 m_chargedNeutralRatio * charged(radius / Athena::Units::cm)) *
101 sensorAccumulatedLumi / maxSensorLuminosity;
102}
103
104double HGTD_TimeResolutionTool::sigmaLandau(const double fluence) const {
105
106 // Parametrization of sensor bias voltage as a function of fluence in 1e14
107 // neq/cm^2. Returns voltage in V.
108 ROOT::Math::Polynomial biasVoltageVsFluence(20.59, 96.26);
109
110 // LGADs can be biased at max 550 V due to single-event burnout. Unit V
111 const double operatingBiasVoltage{
112 std::min(biasVoltageVsFluence(fluence / 1.0e14), 550.0)};
113
114 constexpr double sensorActiveThickness{50.0 * Athena::Units::um};
115 constexpr double gainLayerVoltage{25.0}; // Unit V
116
117 const double averageElectricField{
118 (operatingBiasVoltage - gainLayerVoltage) /
119 (sensorActiveThickness / Athena::Units::um)}; // Unit V/um
120
121 // Parametrization of the Landau fluctuation contribution to time resolution
122 // as a function of average electric field in V/um: c1 + c2 / <E>
123 return (24.441 + 20.2311 / averageElectricField) * Athena::Units::picosecond;
124}
125
126double HGTD_TimeResolutionTool::sigmaALTIROCJitter(const double depositedCharge,
127 const double fluence) const {
128
129 constexpr double maxJitter{999.9 * Athena::Units::ns};
130
131 // Handle the case where insufficient charge is collected at high fluence and
132 // jitter goes to infinity.
133 if (fluence > 3.313e15 || depositedCharge == 0.0) {
134 return maxJitter;
135 }
136
137 // Convert deposited charge to fC
138 const double chargeInfC{depositedCharge / (1.0e-15 * Gaudi::Units::coulomb)};
139
140 // Parametrization of the collected charge as a function of fluence in 1e14
141 // neq/cm^2 for a reference 0.56 fC deposited charge.
142 ROOT::Math::Polynomial referenceCollectedChargeVsFluence(-0.01598, -0.0752,
143 20.04);
144
145 const double collectedCharge{
146 referenceCollectedChargeVsFluence(fluence / 1.0e14) * chargeInfC / 0.56};
147
148 return std::min((11.5201 + 36576.2 * std::pow(collectedCharge, -3.87335)) *
149 Athena::Units::picosecond,
150 maxJitter);
151}
152
154
155 return 20.0 / std::sqrt(12.0) * Athena::Units::picosecond;
156}
157
159
160 return 14.0 * Athena::Units::picosecond;
161}
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
Wrapper to avoid constant divisions when using units.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
double sigmaTDC() const
Returns the time resolution contribution from TDC digitization smearing.
double sigmaLandau(const double fluence) const
Returns the time resolution contribution from Landau fluctuations.
double sigmaClock() const
Returns the time resolution contribution from the LHC clock.
Gaudi::Property< double > m_chargedNeutralRatio
HGTD_TimeResolutionTool(const std::string &type, const std::string &name, const IInterface *parent)
double sigmaALTIROCJitter(const double depositedCharge, const double fluence) const
Returns the time resolution contribution from the electronics jitter of ALTIROC.
double replacementCorrectedLuminosity(const double integratedLumi, const double radius) const
Corrects the integrated luminosity for possible module replacements.
double latestReplacementLuminosity(const double integratedLumi, const std::vector< double > &replacementLumis) const
Helper function to determine the latest replacement luminosity.
float timeResolution(const double depositedCharge, const double radius, const double integratedLumi) const
Returns the time resolution of an HGTD pixel.
double sensorFluence(const double sensorAccumulatedLumi, const double radius) const
Returns the fluence received by the sensor in neq/cm^2.