ATLAS Offline Software
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);
17  InitdEdxTable();
18 }
19 
20 MDT_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);
29  InitdEdxTable();
30 }
31 
33 {
34  delete[] m_rtParameters; m_rtParameters=nullptr;
35 }
36 
37 void MDT_Response::InitClusters(double timewindow, double binsize)
38 {
39  m_binsize = binsize;
40  m_timeWindow = timewindow;
43  m_clusters.resize(m_bins);
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
57  m_triggerElectron = 20.;
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;
97  if(m_rtParameters) delete m_rtParameters;
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 
151 void 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 
183 void 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 
253 bool 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 
264 bool 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 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MDT_Response::GenerateQ
int GenerateQ(CLHEP::HepRandomEngine *rndmEngine) const
Definition: MDT_Response.h:120
MDT_Response::m_integrationWindow
double m_integrationWindow
Definition: MDT_Response.h:92
beamspotman.r
def r
Definition: beamspotman.py:672
MDT_Response::m_bins
int m_bins
Definition: MDT_Response.h:96
MDT_Response::m_signalSpeed
double m_signalSpeed
Definition: MDT_Response.h:83
MDT_Response::m_clusters
clusterVec m_clusters
Definition: MDT_Response.h:99
MDT_Response::InitdEdxTable
void InitdEdxTable()
Definition: MDT_Response.cxx:64
MDT_Response::m_difSmearing
double m_difSmearing
Definition: MDT_Response.h:89
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
MDT_Response::m_gammaFactorVec
std::vector< double > m_gammaFactorVec
Definition: MDT_Response.h:79
MDT_Response::m_offset
int m_offset
Definition: MDT_Response.h:95
MDT_Response::m_radius
double m_radius
Definition: MDT_Response.h:72
MDT_Response::m_xhit
double m_xhit
Definition: MDT_Response.h:75
MDT_Response::DoStepping
void DoStepping(CLHEP::HepRandomEngine *rndmEngine)
Definition: MDT_Response.cxx:151
bin
Definition: BinsDiffFromStripMedian.h:43
MDT_Response::InitClusters
void InitClusters(double timewindow, double binsize)
Definition: MDT_Response.cxx:37
MDT_Response::m_amplifier
Amplifier m_amplifier
Definition: MDT_Response.h:98
Amplifier::AddClusters
bool AddClusters(const cluster_vec &clusters)
Definition: Amplifier.cxx:129
Amplifier::SetTriggerElectron
void SetTriggerElectron(double el)
Definition: Amplifier.h:97
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
MDT_Response.h
MDT_Response::m_triggerElectron
double m_triggerElectron
Definition: MDT_Response.h:91
MDT_Response::SigmaDiffusion
double SigmaDiffusion(double r) const
Definition: MDT_Response.h:173
Amplifier::InitResponse
void InitResponse(unsigned int bins, double binsize)
Definition: Amplifier.cxx:97
MDT_Response::m_numberOfClustersPerMmVec
std::vector< double > m_numberOfClustersPerMmVec
Definition: MDT_Response.h:80
MDT_Response::m_pathLength
double m_pathLength
Definition: MDT_Response.h:76
MDT_Response::Reset
void Reset()
Definition: MDT_Response.cxx:245
MDT_Response::Diffusion
double Diffusion(double r, CLHEP::HepRandomEngine *rndmEngine) const
Definition: MDT_Response.h:161
MDT_Response::m_binsize
double m_binsize
Definition: MDT_Response.h:93
lumiFormat.i
int i
Definition: lumiFormat.py:85
MDT_Response::MDT_Response
MDT_Response()
Definition: MDT_Response.cxx:8
MDT_Response::DampingFactor
double DampingFactor(double x)
Definition: MDT_Response.h:136
python.SystemOfUnits.km
float km
Definition: SystemOfUnits.py:110
MDT_Response::m_t0
double m_t0
Definition: MDT_Response.h:101
MDT_Response::InitTubeParameters
void InitTubeParameters()
Definition: MDT_Response.cxx:48
MDT_Response::m_rtParameters
double * m_rtParameters
Definition: MDT_Response.h:87
Amplifier::Reset
void Reset()
Definition: Amplifier.cxx:119
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:82
MDT_Response::m_attLength
double m_attLength
Definition: MDT_Response.h:82
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
Amplifier::SetIntegrationWindow
void SetIntegrationWindow(double win)
Definition: Amplifier.h:101
MDT_Response::m_rtMode
int m_rtMode
Definition: MDT_Response.h:85
MDT_Response::m_timeWindow
double m_timeWindow
Definition: MDT_Response.h:94
extractSporadic.q
list q
Definition: extractSporadic.py:97
MDT_Response::m_clusterDensity
double m_clusterDensity
Definition: MDT_Response.h:78
MDT_Response::DoStep
double DoStep(CLHEP::HepRandomEngine *rndmEngine) const
Definition: MDT_Response.h:114
MDT_Response::~MDT_Response
~MDT_Response()
Definition: MDT_Response.cxx:32
MDT_Response::m_rtNpar
unsigned int m_rtNpar
Definition: MDT_Response.h:86
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
MDT_Response::InitRt
void InitRt()
Definition: MDT_Response.cxx:95
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
MDT_Response::RtoT
double RtoT(double r)
Definition: MDT_Response.h:142
MDT_Response::GetSignal
bool GetSignal(CLHEP::HepRandomEngine *rndmEngine)
Definition: MDT_Response.cxx:253
MDT_Response::m_rhit
double m_rhit
Definition: MDT_Response.h:74