Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Garfield::TrackBichsel Class Reference

#include <TrackBichsel.hh>

+ Inheritance diagram for Garfield::TrackBichsel:

Public Member Functions

 TrackBichsel ()
 
 ~TrackBichsel ()
 
bool NewTrack (const double x0, const double y0, const double z0, const double t0, const double dx0, const double dy0, const double dz0)
 
bool GetCluster (double &xcls, double &ycls, double &zcls, double &tcls, int &n, double &e, double &extra)
 
double GetClusterDensity ()
 
double GetStoppingPower ()
 
void SetDataFile (const std::string filename)
 
- Public Member Functions inherited from Garfield::Track
 Track ()
 
virtual ~Track ()
 
virtual void SetParticle (std::string part)
 
void SetEnergy (const double e)
 
void SetBetaGamma (const double bg)
 
void SetBeta (const double beta)
 
void SetGamma (const double gamma)
 
void SetMomentum (const double p)
 
void SetKineticEnergy (const double ekin)
 
double GetEnergy () const
 
double GetBetaGamma () const
 
double GetBeta () const
 
double GetGamma () const
 
double GetMomentum () const
 
double GetKineticEnergy () const
 
void SetSensor (Sensor *s)
 
virtual bool NewTrack (const double x0, const double y0, const double z0, const double t0, const double dx0, const double dy0, const double dz0)=0
 
virtual bool GetCluster (double &xcls, double &ycls, double &zcls, double &tcls, int &n, double &e, double &extra)=0
 
virtual double GetClusterDensity ()
 
virtual double GetStoppingPower ()
 
void EnablePlotting (ViewDrift *viewer)
 
void DisablePlotting ()
 
void EnableDebugging ()
 
void DisableDebugging ()
 

Additional Inherited Members

- Protected Member Functions inherited from Garfield::Track
void PlotNewTrack (const double x0, const double y0, const double z0)
 
void PlotCluster (const double x0, const double y0, const double z0)
 
- Protected Attributes inherited from Garfield::Track
std::string className
 
double q
 
int spin
 
double mass
 
double energy
 
double beta2
 
bool isElectron
 
std::string particleName
 
Sensorsensor
 
bool isChanged
 
bool usePlotting
 
ViewDriftviewer
 
bool debug
 
int plotId
 

Detailed Description

Definition at line 13 of file TrackBichsel.hh.

Constructor & Destructor Documentation

◆ TrackBichsel()

Garfield::TrackBichsel::TrackBichsel ( )

Definition at line 15 of file TrackBichsel.cc.

16 : bg(3.16228),
17 speed(SpeedOfLight * bg / sqrt(1. + bg * bg)),
18 x(0.),
19 y(0.),
20 z(0.),
21 t(0.),
22 dx(0.),
23 dy(0.),
24 dz(1.),
25 imfp(4.05090e4),
26 datafile("SiM0invw.inv"),
27 iCdf(2),
28 nCdfEntries(-1),
29 isInitialised(false),
30 isInMedium(false) {
31
32 className = "TrackBichsel";
33}
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
std::string className
Definition: Track.hh:61

◆ ~TrackBichsel()

Garfield::TrackBichsel::~TrackBichsel ( )
inline

Definition at line 19 of file TrackBichsel.hh.

19{}

Member Function Documentation

◆ GetCluster()

bool Garfield::TrackBichsel::GetCluster ( double &  xcls,
double &  ycls,
double &  zcls,
double &  tcls,
int &  n,
double &  e,
double &  extra 
)
virtual

Implements Garfield::Track.

Definition at line 116 of file TrackBichsel.cc.

117 {
118
119 if (!isInitialised || !isInMedium) return false;
120
121 double d = -log(RndmUniformPos()) / imfp;
122 x += dx * d;
123 y += dy * d;
124 z += dz * d;
125 t += d / speed;
126
127 xcls = x;
128 ycls = y;
129 zcls = z;
130 tcls = t;
131 n = 0;
132 e = 0.;
133 extra = 0.;
134
135 Medium* medium;
136 if (!sensor->GetMedium(x, y, z, medium)) {
137 isInMedium = false;
138 if (debug) {
139 std::cout << className << "::GetCluster:\n";
140 std::cout << " Particle left the medium.\n";
141 }
142 return false;
143 }
144
145 if (medium->GetName() != "Si" || !medium->IsIonisable()) {
146 isInMedium = false;
147 if (debug) {
148 std::cout << className << "::GetCluster:\n";
149 std::cout << " Particle left the medium.\n";
150 }
151 return false;
152 }
153
154 const double u = nCdfEntries * RndmUniform();
155 const int j = int(u);
156 if (j == 0) {
157 e = 0. + u * cdf[0][iCdf];
158 } else if (j >= nCdfEntries) {
159 e = cdf[nCdfEntries - 1][iCdf];
160 } else {
161 e = cdf[j - 1][iCdf] + (u - j) * (cdf[j][iCdf] - cdf[j - 1][iCdf]);
162 }
163
164 return true;
165}
bool IsIonisable() const
Definition: Medium.hh:59
std::string GetName() const
Definition: Medium.hh:22
bool GetMedium(const double x, const double y, const double z, Medium *&medium)
Definition: Sensor.cc:141
bool debug
Definition: Track.hh:78
Sensor * sensor
Definition: Track.hh:71
double RndmUniform()
Definition: Random.hh:16
double RndmUniformPos()
Definition: Random.hh:19

◆ GetClusterDensity()

double Garfield::TrackBichsel::GetClusterDensity ( )
virtual

Reimplemented from Garfield::Track.

Definition at line 167 of file TrackBichsel.cc.

167 {
168
169 const int nEntries = 38;
170
171 const double tabBg[nEntries] = {
172 0.316, 0.398, 0.501, 0.631, 0.794, 1.000, 1.259, 1.585,
173 1.995, 2.512, 3.162, 3.981, 5.012, 6.310, 7.943, 10.000,
174 12.589, 15.849, 19.953, 25.119, 31.623, 39.811, 50.119, 63.096,
175 79.433, 100.000, 125.893, 158.489, 199.526, 251.189, 316.228, 398.107,
176 501.187, 630.958, 794.329, 1000.000, 1258.926, 1584.894};
177
178 const double tabImfp[nEntries] = {
179 30.32496, 21.14965, 15.06555, 11.05635, 8.43259, 6.72876, 5.63184,
180 4.93252, 4.49174, 4.21786, 4.05090, 3.95186, 3.89531, 3.86471,
181 3.84930, 3.84226, 3.83952, 3.83887, 3.83912, 3.83970, 3.84035,
182 3.84095, 3.84147, 3.84189, 3.84223, 3.84249, 3.84269, 3.84283,
183 3.84293, 3.84300, 3.84304, 3.84308, 3.84310, 3.84311, 3.84312,
184 3.84313, 3.84313, 3.84314};
185
186 if (isChanged) bg = GetBetaGamma();
187
188 if (bg < tabBg[0]) {
189 if (debug) {
190 std::cerr << className << "::GetClusterDensity:\n";
191 std::cerr << " Bg is below the tabulated range.\n";
192 }
193 return tabImfp[0] * 1.e4;
194 } else if (bg > tabBg[nEntries - 1]) {
195 return tabImfp[nEntries - 1] * 1.e4;
196 }
197
198 // Locate the requested energy in the table
199 int iLow = 0;
200 int iUp = nEntries - 1;
201 int iM;
202 while (iUp - iLow > 1) {
203 iM = (iUp + iLow) >> 1;
204 if (bg >= tabBg[iM]) {
205 iLow = iM;
206 } else {
207 iUp = iM;
208 }
209 }
210
211 if (fabs(bg - tabBg[iLow]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
212 return tabImfp[iLow] * 1.e4;
213 }
214 if (fabs(bg - tabBg[iUp]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
215 return tabImfp[iUp] * 1.e4;
216 }
217
218 // Log-log interpolation
219 const double logX0 = log(tabBg[iLow]);
220 const double logX1 = log(tabBg[iUp]);
221 const double logY0 = log(tabImfp[iLow]);
222 const double logY1 = log(tabImfp[iUp]);
223 double d = logY0 + (log(bg) - logX0) * (logY1 - logY0) / (logX1 - logX0);
224 return 1.e4 * exp(d);
225}
DoubleAc exp(const DoubleAc &f)
Definition: DoubleAc.cpp:376
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:616
double GetBetaGamma() const
Definition: Track.hh:32
bool isChanged
Definition: Track.hh:73

Referenced by NewTrack().

◆ GetStoppingPower()

double Garfield::TrackBichsel::GetStoppingPower ( )
virtual

Reimplemented from Garfield::Track.

Definition at line 227 of file TrackBichsel.cc.

227 {
228
229 const int nEntries = 51;
230
231 const double tabBg[nEntries] = {
232 0.316, 0.398, 0.501, 0.631, 0.794, 1.000, 1.259,
233 1.585, 1.995, 2.512, 3.162, 3.981, 5.012, 6.310,
234 7.943, 10.000, 12.589, 15.849, 19.953, 25.119, 31.623,
235 39.811, 50.119, 63.096, 79.433, 100.000, 125.893, 158.489,
236 199.526, 251.189, 316.228, 398.107, 501.187, 630.958, 794.329,
237 1000.000, 1258.926, 1584.894, 1995.263, 2511.888, 3162.280, 3981.074,
238 5011.875, 6309.578, 7943.287, 10000.010, 12589.260, 15848.940, 19952.640,
239 25118.880, 31622.800};
240
241 const double tabdEdx[nEntries] = {
242 2443.71800, 1731.65600, 1250.93400, 928.69920, 716.37140, 578.28850,
243 490.83670, 437.33820, 406.58490, 390.95170, 385.29000, 386.12000,
244 391.07730, 398.53930, 407.39420, 416.90860, 426.63010, 436.30240,
245 445.78980, 455.02530, 463.97370, 472.61410, 480.92980, 488.90240,
246 496.51900, 503.77130, 510.65970, 517.19570, 523.39830, 529.29120,
247 534.90670, 540.27590, 545.42880, 550.39890, 555.20800, 559.88820,
248 564.45780, 568.93850, 573.34700, 577.69140, 581.99010, 586.25090,
249 590.47720, 594.68660, 598.86880, 603.03510, 607.18890, 611.33250,
250 615.46810, 619.59740, 623.72150};
251
252 if (isChanged) bg = GetBetaGamma();
253
254 if (bg < tabBg[0]) {
255 if (debug) {
256 std::cerr << className << "::GetStoppingPower:\n";
257 std::cerr << " Bg is below the tabulated range.\n";
258 }
259 return tabdEdx[0] * 1.e4;
260 } else if (bg > tabBg[nEntries - 1]) {
261 return tabdEdx[nEntries - 1] * 1.e4;
262 }
263
264 // Locate the requested energy in the table
265 int iLow = 0;
266 int iUp = nEntries - 1;
267 int iM;
268 while (iUp - iLow > 1) {
269 iM = (iUp + iLow) >> 1;
270 if (bg >= tabBg[iM]) {
271 iLow = iM;
272 } else {
273 iUp = iM;
274 }
275 }
276
277 if (debug) {
278 std::cout << className << "::GetStoppingPower:\n";
279 std::cout << " Bg = " << bg << "\n";
280 std::cout << " Interpolating between " << tabBg[iLow] << " and "
281 << tabBg[iUp] << "\n";
282 }
283
284 if (fabs(bg - tabBg[iLow]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
285 return tabdEdx[iLow] * 1.e4;
286 }
287 if (fabs(bg - tabBg[iUp]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
288 return tabdEdx[iUp] * 1.e4;
289 }
290
291 // Log-log interpolation
292 const double logX0 = log(tabBg[iLow]);
293 const double logX1 = log(tabBg[iUp]);
294 const double logY0 = log(tabdEdx[iLow]);
295 const double logY1 = log(tabdEdx[iUp]);
296 const double dedx =
297 logY0 + (log(bg) - logX0) * (logY1 - logY0) / (logX1 - logX0);
298 return 1.e4 * exp(dedx);
299}

◆ NewTrack()

bool Garfield::TrackBichsel::NewTrack ( const double  x0,
const double  y0,
const double  z0,
const double  t0,
const double  dx0,
const double  dy0,
const double  dz0 
)
virtual

Implements Garfield::Track.

Definition at line 35 of file TrackBichsel.cc.

37 {
38
39 // Make sure a sensor has been defined.
40 if (sensor == 0) {
41 std::cerr << className << "::NewTrack:\n";
42 std::cerr << " Sensor is not defined.\n";
43 isInMedium = false;
44 return false;
45 }
46
47 // If not yet done, load the cross-section table from file.
48 if (!isInitialised) {
49 if (!LoadCrossSectionTable(datafile)) {
50 std::cerr << className << "::NewTrack:\n";
51 std::cerr << " Cross-section table could not be loaded.\n";
52 return false;
53 }
54 isInitialised = true;
55 }
56
57 // Make sure we are inside a medium.
58 Medium* medium;
59 if (!sensor->GetMedium(x0, y0, z0, medium)) {
60 std::cerr << className << "::NewTrack:\n";
61 std::cerr << " No medium at initial position.\n";
62 isInMedium = false;
63 return false;
64 }
65
66 // Check if the medium is silicon.
67 if (medium->GetName() != "Si") {
68 std::cerr << className << "::NewTrack:" << std::endl;
69 std::cerr << " Medium at initial position is not silicon.\n";
70 isInMedium = false;
71 return false;
72 }
73
74 // Check if primary ionisation has been enabled.
75 if (!medium->IsIonisable()) {
76 std::cerr << className << "::NewTrack:\n";
77 std::cerr << " Medium at initial position is not ionisable.\n";
78 isInMedium = false;
79 return false;
80 }
81
82 isInMedium = true;
83 x = x0;
84 y = y0;
85 z = z0;
86 t = t0;
87
88 // Normalise the direction vector.
89 const double d = sqrt(dx0 * dx0 + dy0 * dy0 + dz0 * dz0);
90 if (d < Small) {
91 // In case of a null vector, choose a random direction.
92 const double phi = TwoPi * RndmUniform();
93 const double ctheta = 1. - 2. * RndmUniform();
94 const double stheta = sqrt(1. - ctheta * ctheta);
95 dx = cos(phi) * stheta;
96 dy = sin(phi) * stheta;
97 dz = ctheta;
98 } else {
99 dx = dx0 / d;
100 dy = dy0 / d;
101 dz = dz0 / d;
102 }
103
104 // If the particle properties have changed, update the cross-section table.
105 if (isChanged) {
106 bg = GetBetaGamma();
107 imfp = GetClusterDensity();
108 speed = SpeedOfLight * GetBeta();
109 SelectCrossSectionTable();
110 isChanged = false;
111 }
112
113 return true;
114}
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:431
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:383
double GetBeta() const
Definition: Track.hh:33

◆ SetDataFile()

void Garfield::TrackBichsel::SetDataFile ( const std::string  filename)
inline

Definition at line 30 of file TrackBichsel.hh.

30{ datafile = filename; }

The documentation for this class was generated from the following files: