ATLAS Offline Software
Loading...
Searching...
No Matches
MDT_Response.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "CLHEP/Random/RanluxEngine.h"
7
9 m_rhit(0.0),
10 m_xhit(0.0),
11 m_pathLength(0.0),
12 m_rtParameters(nullptr),
13 m_t0(0.0)
14{
16 InitClusters(200.,0.2);
18}
19
20MDT_Response::MDT_Response(double timewindow, double binsize) :
21 m_rhit(0.0),
22 m_xhit(0.0),
23 m_pathLength(0.0),
24 m_rtParameters(nullptr),
25 m_t0(0.0)
26{
28 InitClusters(timewindow,binsize);
30}
31
36
37void MDT_Response::InitClusters(double timewindow, double binsize)
38{
39 m_binsize = binsize;
40 m_timeWindow = timewindow;
43 m_clusters.resize(m_bins);
44 m_amplifier.InitResponse(m_bins,binsize);
45 //std::cout << "MDT_Response Initialize: new cluster vector with " << m_clusters.size() << " bins " << m_bins << std::endl;
46}
47
49{
50 m_radius = 14.6275; // tube radius in atlas
51 m_clusterDensity = 10.; // clusters per mm for 100 GeV muon
52 m_attLength = 30000.; // mm
53 m_signalSpeed = 300.; // mm/ns
54 m_rtMode = 2;
55 m_difSmearing = 10.;
56 m_integrationWindow = 18.5; // ns
58 m_amplifier.SetTriggerElectron(m_triggerElectron);
59 m_amplifier.SetIntegrationWindow(m_integrationWindow);
60 InitRt();
61
62}
63
65{
66
67 // initialize number of clusters per mm vs gamma table
68
69 double gammaFactor[] = {0.10110E+01,0.10133E+01,0.10162E+01,0.10196E+01,0.10237E+01,0.10287E+01,0.10348E+01,0.10422E+01,0.10511E+01,
70 0.10619E+01,0.10750E+01,0.10909E+01,0.11101E+01,0.11334E+01,0.11616E+01,0.11957E+01,0.12371E+01,0.12873E+01,
71 0.13481E+01,0.14217E+01,0.15109E+01,0.16190E+01,0.17499E+01,0.19085E+01,0.21007E+01,0.23335E+01,0.26156E+01,
72 0.29573E+01,0.33714E+01,0.38730E+01,0.44807E+01,0.52170E+01,0.61090E+01,0.71897E+01,0.84989E+01,0.10085E+02,
73 0.12007E+02,0.14335E+02,0.17156E+02,0.20573E+02,0.24714E+02,0.29730E+02,0.35807E+02,0.43170E+02,0.52090E+02,
74 0.62897E+02,0.75989E+02,0.91852E+02,0.11107E+03,0.13435E+03,0.16256E+03,0.19673E+03,0.23814E+03,0.28830E+03,
75 0.34907E+03,0.42270E+03,0.51190E+03,0.61997E+03,0.75089E+03,0.90952E+03,0.11017E+04,0.13345E+04,0.16166E+04,
76 0.19583E+04,0.23724E+04,0.28740E+04,0.34817E+04,0.42180E+04,0.51100E+04,0.61907E+04,0.74999E+04,0.90862E+04,
77 0.11008E+05,0.13336E+05,0.16157E+05,0.19574E+05,0.23715E+05,0.28731E+05,0.34808E+05,0.42171E+05,0.51091E+05,
78 0.61898E+05,0.74990E+05,0.90853E+05,0.11007E+06,0.13335E+06,0.16156E+06,0.19574E+06,0.23714E+06,0.28730E+06,
79 0.34807E+06,0.42170E+06,0.51090E+06,0.61897E+06,0.74990E+06,0.90852E+06};
80
81 double numberOfClustersPerMm[] = {188.7333, 160.5230, 135.5958, 115.2599, 98.1318, 83.4168, 70.8906, 60.3481, 51.4957, 44.0192, 37.6769,
82 32.36505, 27.9281, 24.1556, 21.0378, 18.4179, 16.2422, 14.4153, 12.9175, 11.6626, 10.6435, 9.8294, 9.1667, 8.6551, 8.2926, 7.9775,
83 7.7862, 7.656, 7.5869, 7.5707, 7.6145, 7.6727, 7.7725, 7.8923, 8.0268, 8.2013, 8.3624, 8.5358, 8.7236, 8.9275, 9.1214, 9.2668, 9.3918, 9.5144,
84 9.6032, 9.6733, 9.7272, 9.7535, 9.7837, 9.8438, 9.8365, 9.8620, 9.8892, 9.9119, 9.9063, 9.9235, 9.9267, 9.9175, 9.9299, 9.9409, 9.9269, 9.9437,
85 9.9463, 9.9532, 9.9531, 9.9576, 9.9635, 9.9623, 9.9214, 9.9636, 9.9377, 9.9508, 9.9591, 9.9694, 9.937, 9.9606, 9.9611, 9.9481, 9.9492, 9.9469,
86 9.9401, 9.9232, 9.9566, 9.9532, 9.9514, 9.9550, 9.9714, 9.9504, 9.9726, 9.9381, 9.9259, 9.9633, 9.9455, 9.9560, 9.9693, 9.9516};
87
88 for( int ik = 0; ik < 96; ++ik ) {
89 m_gammaFactorVec.push_back( gammaFactor[ik] );
90 m_numberOfClustersPerMmVec.push_back( numberOfClustersPerMm[ik] );
91 }
92}
93
94
96 //std::cout << "Setting rt-relation" << std::endl;
98 switch(m_rtMode){
99 case 0: /* linear rt */
100 m_rtNpar = 1;
101 m_rtParameters = new double[m_rtNpar];
102 m_rtParameters[0] = 700./m_radius;
103 break;
104 case 1: /* used for work presented in muonsw nov 2003 */
105 m_rtNpar = 4;
106 m_rtParameters = new double[m_rtNpar];
107 m_rtParameters[0] = 0.;
108 m_rtParameters[1] = 16.4;
109 m_rtParameters[2] = 0.43;
110 m_rtParameters[3] = 0.102;
111 break;
112 case 2: // garfield rt-relation
113 m_rtNpar = 10;
114 m_rtParameters = new double[m_rtNpar];
115 m_rtParameters[0] = -1.79390e-01;
116 m_rtParameters[1] = 2.04417e+01;
117 m_rtParameters[2] = 4.96576e+00;
118 m_rtParameters[3] = -2.59002e+00;
119 m_rtParameters[4] = 5.45522e-01;
120 m_rtParameters[5] = -4.66626e-02;
121 m_rtParameters[6] = 5.66214e-04;
122 m_rtParameters[7] = 1.89740e-04;
123 m_rtParameters[8] = -1.30073e-05;
124 m_rtParameters[9] = 2.68995e-07;
125 break;
126 case 3: // output rt-relation
127 m_rtNpar = 10;
128 m_rtParameters = new double[m_rtNpar];
129 m_rtParameters[0] = 2.31708e+01;
130 m_rtParameters[1] = 4.55828;
131 m_rtParameters[2] = 1.41878e+01;
132 m_rtParameters[3] = -5.99392;
133 m_rtParameters[4] = 1.34392;
134 m_rtParameters[5] = -1.65248e-01;
135 m_rtParameters[6] = 1.15960e-02;
136 m_rtParameters[7] = -4.29922e-04;
137 m_rtParameters[8] = 6.14201e-06;
138 m_rtParameters[9] = 2.00429e-08;
139 break;
140 default:
141 std::cout << "MDT_Response: Wrong rt-mode" << std::endl;
142 m_rtNpar = 0;
143 m_rtParameters = nullptr;
144 break;
145 }
146// std::cout << "MDT_Response: RT-relation -> Polynomial" << std::endl;
147// for(unsigned int i=0;i<m_rtNpar;++i)
148// std::cout << " Par[" << i << "] = " << m_rtParameters[i] << std::endl;
149}
150
151void MDT_Response::DoStepping(CLHEP::HepRandomEngine *rndmEngine)
152{
153 //double propDelay = PropagationDelay(m_xhit);
154 double damping = DampingFactor(m_xhit);
155 double r2(m_rhit*m_rhit);
156 m_t0 = RtoT(m_rhit);
157
158 for(int i=0;i<2;++i){ // splite track into to segments
159 double cl(0.); // current position along track
160 while(cl < m_pathLength){
161 cl += DoStep(rndmEngine); // Do step along track
162 double r = sqrt(cl*cl + r2); // calculate corresponding r
163 int q = GenerateQ(rndmEngine);// generate cluster size
164 double t = RtoT(r);
165 // check if value lies within window
166 if(t-m_t0 > m_bins*m_binsize + 3.*SigmaDiffusion(r) ) {
167 break;
168 }
169 double tc = t + Diffusion(r, rndmEngine) - m_t0;
170 int bin( (int)(tc/m_binsize+m_offset) );
171
172 // fill value into corresponding bin
173 if(bin < (int)m_clusters.size() && bin >=0 ){
174 m_clusters[bin] += q*damping;
175 }else if(bin < 0) {
176 std::cout << "out of range " << tc << " bin " << bin << std::endl;
177 }
178 }
179 }
180}
181
182
183void MDT_Response::DoStepping(double ParticleCharge,double ParticleGamma, CLHEP::HepRandomEngine *rndmEngine)
184{
185// extract Cluster Density for the given value of particle gamma from the vector gammaFactorVec()
186 double correctedClusterDensity;
187 int km=0;
188 int kmm=0;
189 if(ParticleGamma<0.90852E+06){
190 while(ParticleGamma>m_gammaFactorVec.at(km)){
191 ++km;
192 }
193 int mm=km-1;
194 if(km!=0){
195 double deltagamma=fabs(m_gammaFactorVec.at(km)-m_gammaFactorVec.at(mm))/2.;
196 kmm=km-1;
197 if(ParticleGamma > (m_gammaFactorVec.at(mm)+deltagamma)){
198 kmm=km;
199 }
200 }
201 correctedClusterDensity = m_numberOfClustersPerMmVec.at(kmm);
202 }else{
203 correctedClusterDensity = m_clusterDensity; // response plateaus: default to value for 100 GeV muon
204 }
205
206 //double propDelay = PropagationDelay(m_xhit);
207 double damping = DampingFactor(m_xhit);
208 double r2(m_rhit*m_rhit);
209 m_t0 = RtoT(m_rhit);
210
211 for(int i=0;i<2;++i){ // splite track into to segments
212 double cl(0.); // current position along track
213 while(cl < m_pathLength){
214
215 if(fabs(ParticleCharge)!=1.){
216 cl += m_clusterDensity/(correctedClusterDensity*pow(ParticleCharge,2))*DoStep(rndmEngine); // Do step along track
217 }else{
218 cl += m_clusterDensity/(correctedClusterDensity)*DoStep(rndmEngine); // Do step along track
219 }
220
221 double r = sqrt(cl*cl + r2); // calculate corresponding r
222 int q = GenerateQ(rndmEngine); // generate cluster size
223 double t = RtoT(r);
224 // check if value lies within window
225 if(t-m_t0 > m_bins*m_binsize + 3.*SigmaDiffusion(r) ) {
226 break;
227 }
228 double tc = t + Diffusion(r, rndmEngine) - m_t0;
229 int bin( (int)(tc/m_binsize+m_offset) );
230
231 // fill value into corresponding bin
232 if(bin < (int)m_clusters.size() && bin >=0 ){
233 m_clusters[bin] += q*damping;
234 }else if(bin < 0) {
235 std::cout << "out of range " << tc << " bin " << bin << std::endl;
236 }
237 }
238 }
239}
240
241
242
243
244
246{
247 clusterVec::iterator cit = m_clusters.begin();
248 for( ; cit != m_clusters.end() ; ++cit)
249 *cit = 0;
250 m_amplifier.Reset();
251}
252
253bool MDT_Response::GetSignal(CLHEP::HepRandomEngine *rndmEngine)
254{
255 // generate and propagate clusters
256 DoStepping(rndmEngine);
257
258 // get amplifier response and see if it passed threshold
259 bool hasSignal = m_amplifier.AddClusters(m_clusters);
260 return hasSignal;
261}
262
263
264bool MDT_Response::GetSignal(double ParticleCharge,double ParticleGamma,CLHEP::HepRandomEngine *rndmEngine)
265{
266 // generate and propagate clusters
267 DoStepping(ParticleCharge,ParticleGamma,rndmEngine);
268
269 // get amplifier response and see if it passed threshold
270 bool hasSignal = m_amplifier.AddClusters(m_clusters);
271 return hasSignal;
272}
static Double_t tc
constexpr int pow(int base, int exp) noexcept
double DoStep(CLHEP::HepRandomEngine *rndmEngine) const
void InitTubeParameters()
unsigned int m_rtNpar
clusterVec m_clusters
double DampingFactor(double x)
double m_attLength
double m_triggerElectron
double m_difSmearing
double Diffusion(double r, CLHEP::HepRandomEngine *rndmEngine) const
double m_radius
void InitdEdxTable()
double m_clusterDensity
int GenerateQ(CLHEP::HepRandomEngine *rndmEngine) const
double m_binsize
double SigmaDiffusion(double r) const
double m_integrationWindow
double RtoT(double r)
void InitClusters(double timewindow, double binsize)
double m_pathLength
Amplifier m_amplifier
bool GetSignal(CLHEP::HepRandomEngine *rndmEngine)
std::vector< double > m_gammaFactorVec
double m_timeWindow
void DoStepping(CLHEP::HepRandomEngine *rndmEngine)
std::vector< double > m_numberOfClustersPerMmVec
double * m_rtParameters
double m_signalSpeed
int r
Definition globals.cxx:22