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

#include <TrackPAI.hh>

+ Inheritance diagram for Garfield::TrackPAI:

Public Member Functions

 TrackPAI ()
 
 ~TrackPAI ()
 
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 &ncls, double &ecls, double &extra)
 
double GetClusterDensity ()
 
double GetStoppingPower ()
 
- 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 TrackPAI.hh.

Constructor & Destructor Documentation

◆ TrackPAI()

Garfield::TrackPAI::TrackPAI ( )

Definition at line 13 of file TrackPAI.cc.

14 : ready(false),
15 x(0.),
16 y(0.),
17 z(0.),
18 t(0.),
19 dx(0.),
20 dy(0),
21 dz(1.),
22 e(0.),
23 speed(0.),
24 emax(0.),
25 imfp(0.),
26 dedx(0.),
27 nSteps(1000),
28 mediumName(""),
29 mediumDensity(0.),
30 electronDensity(0.) {
31
32 className = "TrackPAI";
33
34 electrons.clear();
35 holes.clear();
36}
std::string className
Definition: Track.hh:61

◆ ~TrackPAI()

Garfield::TrackPAI::~TrackPAI ( )
inline

Definition at line 19 of file TrackPAI.hh.

19{}

Member Function Documentation

◆ GetCluster()

bool Garfield::TrackPAI::GetCluster ( double &  xcls,
double &  ycls,
double &  zcls,
double &  tcls,
int &  ncls,
double &  ecls,
double &  extra 
)
virtual

Implements Garfield::Track.

Definition at line 115 of file TrackPAI.cc.

117 {
118
119 ncls = 0;
120 edep = extra = 0.;
121
122 // Clear the stack.
123 electrons.clear();
124 holes.clear();
125
126 if (!ready) {
127 std::cerr << className << "::GetCluster:\n";
128 std::cerr << " Track not initialized.\n";
129 std::cerr << " Call NewTrack first.\n";
130 return false;
131 }
132
133 if (isChanged) {
134 if (SetupCrossSectionTable()) {
135 isChanged = false;
136 } else {
137 std::cerr << className << "::GetCluster:\n";
138 std::cerr << " Calculation of ionisation cross-section failed.\n";
139 return false;
140 }
141 }
142
143 // Draw a step length and propagate the particle.
144 const double d = -imfp * log(RndmUniformPos());
145 x += d * dx;
146 y += d * dy;
147 z += d * dz;
148 t += d / speed;
149
150 // Check the medium at this location.
151 Medium* medium = 0;
152 if (!sensor->GetMedium(x, y, z, medium)) {
153 ready = false;
154 return false;
155 }
156 if (medium->GetName() != mediumName ||
157 medium->GetNumberDensity() != mediumDensity || !medium->IsIonisable()) {
158 ready = false;
159 return false;
160 }
161
162 // Check if the particle is still inside the drift area.
163 if (!sensor->IsInArea(x, y, z)) {
164 ready = false;
165 return false;
166 }
167
168 xcls = x;
169 ycls = y;
170 zcls = z;
171 tcls = t;
172
173 // Sample the energy deposition.
174 double f = 0.;
175 const double u = RndmUniform();
176 if (u < cdf.back()) {
177 if (u <= cdf[0]) {
178 edep = energies[0];
179 } else if (u >= 1.) {
180 edep = energies.back();
181 } else {
182 // Find the energy loss by interpolation
183 // from the cumulative distribution table
184 int iLow = 0, iUp = cdf.size(), iMid;
185 while (iUp - iLow > 1) {
186 iMid = (iUp + iLow) >> 1;
187 if (u >= cdf[iMid]) {
188 iLow = iMid;
189 } else {
190 iUp = iMid;
191 }
192 }
193 if (edep < 100.) {
194 edep = energies[iLow] + (u - cdf[iLow]) *
195 (energies[iUp] - energies[iLow]) /
196 (cdf[iUp] - cdf[iLow]);
197 f = rutherford[iLow] + (edep - energies[iLow]) *
198 (rutherford[iUp] - rutherford[iLow]) /
199 (energies[iUp] - energies[iLow]);
200 } else {
201 edep = log(energies[iLow]) +
202 (log(u) - log(cdf[iLow])) *
203 (log(energies[iUp]) - log(energies[iLow])) /
204 (log(cdf[iUp]) - log(cdf[iLow]));
205 edep = exp(edep);
206 f = rutherford[iLow] + (log(edep) - log(energies[iLow])) *
207 (rutherford[iUp] - rutherford[iLow]) /
208 (log(energies[iUp]) - log(energies[iLow]));
209 }
210 }
211 } else {
212 // Use the free-electron differential cross-section.
213 f = 1.;
214 edep = SampleAsymptoticCs(u);
215 }
216 // Update the particle energy.
217 e -= edep;
218
219 // Number of electron/hole (or electron/ion pairs) produced.
220 ncls = 1;
221
222 if (debug) {
223 std::cout << className << "::GetCluster:\n";
224 std::cout << " Fraction of Rutherford scattering: " << f << "\n";
225 }
226 return true;
227}
DoubleAc exp(const DoubleAc &f)
Definition: DoubleAc.cpp:376
virtual double GetNumberDensity() const
Definition: Medium.hh:47
bool IsIonisable() const
Definition: Medium.hh:59
std::string GetName() const
Definition: Medium.hh:22
bool IsInArea(const double x, const double y, const double z)
Definition: Sensor.cc:254
bool GetMedium(const double x, const double y, const double z, Medium *&medium)
Definition: Sensor.cc:141
bool isChanged
Definition: Track.hh:73
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::TrackPAI::GetClusterDensity ( )
virtual

Reimplemented from Garfield::Track.

Definition at line 309 of file TrackPAI.cc.

309 {
310
311 if (!ready) {
312 std::cerr << className << "::GetClusterDensity:\n";
313 std::cerr << " Track has not been initialized.\n";
314 return 0.;
315 }
316
317 if (isChanged) {
318 if (SetupCrossSectionTable()) {
319 isChanged = false;
320 } else {
321 std::cerr << className << "::GetClusterDensity:\n";
322 std::cerr << " Ionisation cross-section could not be calculated.\n";
323 return 0.;
324 }
325 }
326
327 return 1. / imfp;
328}

◆ GetStoppingPower()

double Garfield::TrackPAI::GetStoppingPower ( )
virtual

Reimplemented from Garfield::Track.

Definition at line 330 of file TrackPAI.cc.

330 {
331
332 if (!ready) {
333 std::cerr << className << "::GetStoppingPower:\n";
334 std::cerr << " Track has not been initialised.\n";
335 return 0.;
336 }
337
338 if (isChanged) {
339 if (SetupCrossSectionTable()) {
340 isChanged = false;
341 } else {
342 std::cerr << className << "::GetStoppingPower:\n";
343 std::cerr << " Ionisation cross-section could not be calculated.\n";
344 return 0.;
345 }
346 }
347
348 return dedx;
349}

◆ NewTrack()

bool Garfield::TrackPAI::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 38 of file TrackPAI.cc.

40 {
41
42 ready = false;
43
44 // Make sure the sensor has been set.
45 if (sensor == 0) {
46 std::cerr << className << "::NewTrack:\n";
47 std::cerr << " Sensor is not defined.\n";
48 return false;
49 }
50
51 // Get the medium at this location and check if it is "ionisable".
52 Medium* medium = 0;
53 if (!sensor->GetMedium(x0, y0, z0, medium)) {
54 std::cerr << className << "::NewTrack:\n";
55 std::cerr << " No medium at initial position.\n";
56 return false;
57 }
58 if (!medium->IsIonisable()) {
59 std::cerr << className << "::NewTrack:\n";
60 std::cerr << " Medium at initial position is not ionisable.\n";
61 return false;
62 }
63
64 if (medium->GetName() != mediumName ||
65 medium->GetNumberDensity() != mediumDensity) {
66 isChanged = true;
67 if (!SetupMedium(medium)) {
68 std::cerr << className << "::NewTrack:\n";
69 std::cerr << " Properties of medium " << medium->GetName()
70 << " are not available.\n";
71 return false;
72 }
73 mediumName = medium->GetName();
74 mediumDensity = medium->GetNumberDensity();
75 }
76
77 ready = true;
78
79 if (isChanged) {
80 if (!SetupCrossSectionTable()) {
81 std::cerr << className << "::NewTrack:\n";
82 std::cerr << " Calculation of ionisation cross-section failed.\n";
83 ready = false;
84 return false;
85 }
86 isChanged = false;
87 }
88
89 x = x0;
90 y = y0;
91 z = z0;
92 t = t0;
93 const double d = sqrt(dx0 * dx0 + dy0 * dy0 + dz0 * dz0);
94 if (d < Small) {
95 if (debug) {
96 std::cout << className << "::NewTrack:\n";
97 std::cout << " Direction vector has zero norm.\n";
98 std::cout << " Initial direction is randomized.\n";
99 }
100 const double ctheta = 1. - 2. * RndmUniform();
101 const double stheta = sqrt(1. - ctheta * ctheta);
102 const double phi = TwoPi * RndmUniform();
103 dx = cos(phi) * stheta;
104 dy = sin(phi) * stheta;
105 dz = ctheta;
106 } else {
107 // Normalize the direction vector.
108 dx = dx0 / d;
109 dy = dy0 / d;
110 dz = dz0 / d;
111 }
112 return true;
113}
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:431
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:313
DoubleAc sin(const DoubleAc &f)
Definition: DoubleAc.cpp:383

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