Garfield++ v2r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
AvalancheMicroscopic.hh
Go to the documentation of this file.
1#ifndef G_AVALANCHE_MICROSCOPIC_H
2#define G_AVALANCHE_MICROSCOPIC_H
3
4#include <vector>
5#include <string>
6
7#include <TH1.h>
8
9#include "Sensor.hh"
10#include "ViewDrift.hh"
11#include "GarfieldConstants.hh"
12
13namespace Garfield {
14
15/// Calculate electron drift lines and avalanches using microscopic tracking.
16
18
19 public:
20 /// Constructor
22 /// Destructor
24
25 /// Set the sensor.
26 void SetSensor(Sensor* sensor);
27
28 /// Switch on drift line plotting.
29 void EnablePlotting(ViewDrift* view);
30 void DisablePlotting();
31 /// Draw a marker at every excitation.
32 void EnableExcitationMarkers() { m_plotExcitations = true; }
33 void DisableExcitationMarkers() { m_plotExcitations = false; }
34 /// Draw a marker at every ionising collision.
35 void EnableIonisationMarkers() { m_plotIonisations = true; }
36 void DisableIonisationMarkers() { m_plotIonisations = false; }
37 /// Draw a marker at every attachment.
38 void EnableAttachmentMarkers() { m_plotAttachments = true; }
39 void DisableAttachmentMarkers() { m_plotAttachments = false; }
40
41 /// Switch on calculation of induced currents
42 void EnableSignalCalculation() { m_useSignal = true; }
43 void DisableSignalCalculation() { m_useSignal = false; }
44
45 /// Switch on calculation of the total induced charge
46 void EnableInducedChargeCalculation() { m_useInducedCharge = true; }
47 void DisableInducedChargeCalculation() { m_useInducedCharge = false; }
48
49 /// Switch on filling histograms for electron energy distribution
50 void EnableElectronEnergyHistogramming(TH1* histo);
51 void DisableElectronEnergyHistogramming() { m_histElectronEnergy = NULL; }
52 void EnableHoleEnergyHistogramming(TH1* histo);
53 void DisableHoleEnergyHistogramming() { m_histHoleEnergy = NULL; }
54
55 /** Fill histograms of the distance between successive collisions.
56 * \param histo
57 pointer to the histogram to be filled
58 * \param opt
59 direction ('x', 'y', 'z', 'r')
60 */
61 void SetDistanceHistogram(TH1* histo, const char opt = 'r');
62 void EnableDistanceHistogramming(const int type);
63 /// Switch on distance distribution histograms for a given collision type.
64 void DisableDistanceHistogramming(const int type);
66 /// Fill histograms of the energy of electrons emitted in ionising collisions.
68 void DisableSecondaryEnergyHistogramming() { m_histSecondary = NULL; }
69
70 /// Switch on storage of drift lines.
71 void EnableDriftLines() { m_useDriftLines = true; }
72 void DisableDriftLines() { m_useDriftLines = false; }
73
74 /** Switch on photon transport.
75 * \remark This feature has not been tested thoroughly. */
76 void EnablePhotonTransport() { m_usePhotons = true; }
77 void DisablePhotonTransport() { m_usePhotons = false; }
78
79 /// Switch on stepping according to band structure E(k), for semiconductors.
80 void EnableBandStructure() { m_useBandStructureDefault = true; }
81 void DisableBandStructure() { m_useBandStructureDefault = false; }
82
83 /// Switch on update of coordinates for null-collision steps (default: off).
84 void EnableNullCollisionSteps() { m_useNullCollisionSteps = true; }
85 void DisableNullCollisionSteps() { m_useNullCollisionSteps = false; }
86
87 /** Set a (lower) energy threshold for electron transport.
88 * This can be useful for simulating delta electrons. */
89 void SetElectronTransportCut(const double cut) { m_deltaCut = cut; }
90 double GetElectronTransportCut() const { return m_deltaCut; }
91
92 /// Set an energy threshold for photon transport.
93 void SetPhotonTransportCut(const double cut) { m_gammaCut = cut; }
94 double GetPhotonTransportCut() const { return m_gammaCut; }
95
96 /** Set a max. avalanche size (i. e. ignore ionising collisions
97 once this size has been reached). */
98 void EnableAvalancheSizeLimit(const unsigned int size) { m_sizeCut = size; }
99 void DisableAvalancheSizeLimit() { m_sizeCut = 0; }
100 int GetAvalancheSizeLimit() const { return m_sizeCut; }
101
102 /// Enable magnetic field in stepping algorithm (default: off).
103 void EnableMagneticField() { m_useBfield = true; }
104 void DisableMagneticField() { m_useBfield = false; }
105
106 /// Set number of collisions to be skipped for plotting
107 void SetCollisionSteps(const unsigned int n) { m_nCollSkip = n; }
108
109 /// Define a time interval (only carriers inside the interval are simulated).
110 void SetTimeWindow(const double t0, const double t1);
111 void UnsetTimeWindow();
112
113 /// Return the number of electrons and ions in the avalanche.
114 void GetAvalancheSize(int& ne, int& ni) const {
115 ne = m_nElectrons;
116 ni = m_nIons;
117 }
118 void GetAvalancheSize(int& ne, int& nh, int& ni) const {
119 ne = m_nElectrons;
120 nh = m_nHoles;
121 ni = m_nIons;
122 }
123
124 /** Return the number of electron trajectories in the last
125 * simulated avalanche (including captured electrons). */
126 unsigned int GetNumberOfElectronEndpoints() const {
127 return m_endpointsElectrons.size();
128 }
129 /** Return the coordinates and time of start and end point of a given
130 * electron drift line.
131 * \param i index of the drift line
132 * \param x0,y0,z0,t0 coordinates and time of the starting point
133 * \param x1,y1,z1,t1 coordinates and time of the end point
134 * \param e0,e1 initial and final energy
135 * \param status status code (see GarfieldConstants.hh)
136 */
137 void GetElectronEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
138 double& t0, double& e0, double& x1, double& y1,
139 double& z1, double& t1, double& e1,
140 int& status) const;
141 void GetElectronEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
142 double& t0, double& e0, double& x1, double& y1,
143 double& z1, double& t1, double& e1, double& dx1,
144 double& dy1, double& dz1, int& status) const;
145 unsigned int GetNumberOfElectronDriftLinePoints(const unsigned int i = 0) const;
146 unsigned int GetNumberOfHoleDriftLinePoints(const unsigned int i = 0) const;
147 void GetElectronDriftLinePoint(double& x, double& y, double& z, double& t,
148 const int ip, const unsigned int iel = 0) const;
149 void GetHoleDriftLinePoint(double& x, double& y, double& z, double& t,
150 const int ip, const unsigned int iel = 0) const;
151
152 unsigned int GetNumberOfHoleEndpoints() const {
153 return m_endpointsHoles.size();
154 }
155 void GetHoleEndpoint(const unsigned int i, double& x0, double& y0, double& z0,
156 double& t0, double& e0, double& x1, double& y1,
157 double& z1, double& t1, double& e1, int& status) const;
158
159 unsigned int GetNumberOfPhotons() const { return m_photons.size(); }
160 // Status codes:
161 // -2: photon absorbed by gas molecule
162 void GetPhoton(const unsigned int i, double& e, double& x0, double& y0, double& z0,
163 double& t0, double& x1, double& y1, double& z1, double& t1,
164 int& status) const;
165
166 /** Calculate an electron drift line.
167 * \param x0,y0,z0,t0 starting point of the electron
168 * \param e0 initial energy of the electron
169 * \param dx0,dy0,dz0 initial direction of the electron
170 * If the initial direction is not specified, it is sampled randomly.
171 * Secondary electrons are not transported. */
172 bool DriftElectron(const double x0, const double y0, const double z0,
173 const double t0, const double e0, const double dx0 = 0.,
174 const double dy0 = 0., const double dz0 = 0.);
175
176 /// Calculate an avalanche initiated by a given electron.
177 bool AvalancheElectron(const double x0, const double y0, const double z0,
178 const double t0, const double e0,
179 const double dx0 = 0., const double dy0 = 0.,
180 const double dz0 = 0.);
181
182 /// Set a user handling procedure. This function is called at every step.
183 void SetUserHandleStep(void (*f)(double x, double y, double z, double t,
184 double e, double dx, double dy, double dz,
185 bool hole));
186 void UnsetUserHandleStep();
187 /// Set a user handling procedure, to be called at every attachment.
188 void SetUserHandleAttachment(void (*f)(double x, double y, double z, double t,
189 int type, int level, Medium* m));
191 /// Set a user handling procedure, to be called at every inelastic collision.
192 void SetUserHandleInelastic(void (*f)(double x, double y, double z, double t,
193 int type, int level, Medium* m));
195 /// Set a user handling procedure, to be called at every ionising collision.
196 void SetUserHandleIonisation(void (*f)(double x, double y, double z, double t,
197 int type, int level, Medium* m));
199
200 /// Switch on debugging messages.
201 void EnableDebugging() { m_debug = true; }
202 void DisableDebugging() { m_debug = false; }
203
204 private:
205 std::string m_className;
206
207 Sensor* m_sensor;
208
209 struct point {
210 double x, y, z, t;
211 };
212
213 struct Electron {
214 int status; //< Status.
215 bool hole; //< Electron or hole.
216 double x0, y0, z0, t0; //< Starting point and time.
217 double e0; //< Initial kinetic energy.
218 int band; //< Band.
219 double x, y, z, t; //< Current position and time.
220 double kx, ky, kz; //< Current direction/wave vector.
221 double energy; //< Current kinetic energy.
222 std::vector<point> driftLine; //< Drift line.
223 double xLast, yLast, zLast; //< Previous position.
224 };
225 std::vector<Electron> m_endpointsElectrons;
226 std::vector<Electron> m_endpointsHoles;
227
228 struct photon {
229 int status; //< Status
230 double energy; //< Energy
231 double x0, y0, z0, t0; //< Starting point and time.
232 double x1, y1, z1, t1; //< End point and time.
233 };
234 std::vector<photon> m_photons;
235
236 /// Number of electrons produced
237 int m_nElectrons;
238 /// Number of holes produced
239 int m_nHoles;
240 /// Number of ions produced
241 int m_nIons;
242
243 bool m_usePlotting;
244 ViewDrift* m_viewer;
245 bool m_plotExcitations;
246 bool m_plotIonisations;
247 bool m_plotAttachments;
248
249 TH1* m_histElectronEnergy;
250 TH1* m_histHoleEnergy;
251 TH1* m_histDistance;
252 char m_distanceOption;
253 std::vector<int> m_distanceHistogramType;
254
255 TH1* m_histSecondary;
256
257 bool m_useSignal;
258 bool m_useInducedCharge;
259 bool m_useDriftLines;
260 bool m_usePhotons;
261 bool m_useBandStructureDefault;
262 bool m_useNullCollisionSteps;
263 bool m_useBfield;
264
265 // Rotation matrices
266 double m_rb11, m_rb12, m_rb13;
267 double m_rb21, m_rb22, m_rb23;
268 double m_rb31, m_rb32, m_rb33;
269 double m_rx22, m_rx23, m_rx32, m_rx33;
270
271 // Transport cuts
272 double m_deltaCut;
273 double m_gammaCut;
274
275 // Max. avalanche size
276 unsigned int m_sizeCut;
277
278 unsigned int m_nCollSkip;
279
280 bool m_hasTimeWindow;
281 double m_tMin, m_tMax;
282
283 // User procedures
284 bool m_hasUserHandleStep;
285 bool m_hasUserHandleAttachment;
286 bool m_hasUserHandleInelastic;
287 bool m_hasUserHandleIonisation;
288 void (*m_userHandleStep)(double x, double y, double z, double t, double e,
289 double dx, double dy, double dz, bool hole);
290 void (*m_userHandleAttachment)(double x, double y, double z, double t, int type,
291 int level, Medium* m);
292 void (*m_userHandleInelastic)(double x, double y, double z, double t, int type,
293 int level, Medium* m);
294 void (*m_userHandleIonisation)(double x, double y, double z, double t, int type,
295 int level, Medium* m);
296
297 // Switch on/off debugging messages
298 bool m_debug;
299
300 // Electron transport
301 bool TransportElectron(const double x0, const double y0, const double z0,
302 const double t0, double e0, const double dx0,
303 const double dy0, const double dz0, const bool aval,
304 bool hole);
305 // Photon transport
306 void TransportPhoton(const double x, const double y, const double z,
307 const double t, const double e,
308 std::vector<Electron>& stack);
309
310 void ComputeRotationMatrix(const double bx, const double by, const double bz,
311 const double bmag, const double ex,
312 const double ey, const double ez);
313
314 void RotateGlobal2Local(double& dx, double& dy, double& dz) const;
315 void RotateLocal2Global(double& dx, double& dy, double& dz) const;
316
317 static bool IsInactive(const Electron& item) {
318
319 return item.status == StatusLeftDriftMedium ||
320 item.status == StatusBelowTransportCut ||
321 item.status == StatusOutsideTimeWindow ||
322 item.status == StatusLeftDriftArea ||
323 item.status == StatusAttached;
324 }
325 void Update(std::vector<Electron>::iterator it,
326 const double x, const double y, const double z,
327 const double t, const double energy,
328 const double kx, const double ky, const double kz,
329 const int band);
330 void AddToEndPoints(const Electron& item, const bool hole) {
331 if (hole) {
332 m_endpointsHoles.push_back(item);
333 } else {
334 m_endpointsElectrons.push_back(item);
335 }
336 }
337
338 /// Add a new electron/hole (with random direction) to a container.
339 void AddToStack(const double x, const double y, const double z,
340 const double t, const double energy,
341 const bool hole,
342 std::vector<Electron>& container) const;
343 /// Add a new electron/hole to a container.
344 void AddToStack(const double x, const double y, const double z,
345 const double t, const double energy,
346 const double dx, const double dy, const double dz,
347 const int band, const bool hole,
348 std::vector<Electron>& container) const;
349 void Terminate(double x0, double y0, double z0, double t0,
350 double& x1, double& y1, double& z1, double& t1);
351};
352}
353
354#endif
Calculate electron drift lines and avalanches using microscopic tracking.
void EnableDistanceHistogramming(const int type)
void SetDistanceHistogram(TH1 *histo, const char opt='r')
void EnableAvalancheSizeLimit(const unsigned int size)
void EnableSignalCalculation()
Switch on calculation of induced currents.
void EnableNullCollisionSteps()
Switch on update of coordinates for null-collision steps (default: off).
void SetUserHandleStep(void(*f)(double x, double y, double z, double t, double e, double dx, double dy, double dz, bool hole))
Set a user handling procedure. This function is called at every step.
void EnableInducedChargeCalculation()
Switch on calculation of the total induced charge.
void EnablePlotting(ViewDrift *view)
Switch on drift line plotting.
void SetUserHandleIonisation(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every ionising collision.
bool DriftElectron(const double x0, const double y0, const double z0, const double t0, const double e0, const double dx0=0., const double dy0=0., const double dz0=0.)
void SetPhotonTransportCut(const double cut)
Set an energy threshold for photon transport.
void EnableExcitationMarkers()
Draw a marker at every excitation.
unsigned int GetNumberOfElectronDriftLinePoints(const unsigned int i=0) const
unsigned int GetNumberOfHoleEndpoints() const
void EnableIonisationMarkers()
Draw a marker at every ionising collision.
void EnableMagneticField()
Enable magnetic field in stepping algorithm (default: off).
void EnableDriftLines()
Switch on storage of drift lines.
void SetCollisionSteps(const unsigned int n)
Set number of collisions to be skipped for plotting.
void GetAvalancheSize(int &ne, int &ni) const
Return the number of electrons and ions in the avalanche.
void SetUserHandleAttachment(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every attachment.
void SetSensor(Sensor *sensor)
Set the sensor.
void GetHoleDriftLinePoint(double &x, double &y, double &z, double &t, const int ip, const unsigned int iel=0) const
void GetElectronEndpoint(const unsigned int i, double &x0, double &y0, double &z0, double &t0, double &e0, double &x1, double &y1, double &z1, double &t1, double &e1, int &status) const
void GetHoleEndpoint(const unsigned int i, double &x0, double &y0, double &z0, double &t0, double &e0, double &x1, double &y1, double &z1, double &t1, double &e1, int &status) const
void GetElectronDriftLinePoint(double &x, double &y, double &z, double &t, const int ip, const unsigned int iel=0) const
void EnableElectronEnergyHistogramming(TH1 *histo)
Switch on filling histograms for electron energy distribution.
void GetPhoton(const unsigned int i, double &e, double &x0, double &y0, double &z0, double &t0, double &x1, double &y1, double &z1, double &t1, int &status) const
void GetAvalancheSize(int &ne, int &nh, int &ni) const
void EnableSecondaryEnergyHistogramming(TH1 *histo)
Fill histograms of the energy of electrons emitted in ionising collisions.
void EnableAttachmentMarkers()
Draw a marker at every attachment.
bool AvalancheElectron(const double x0, const double y0, const double z0, const double t0, const double e0, const double dx0=0., const double dy0=0., const double dz0=0.)
Calculate an avalanche initiated by a given electron.
void EnableBandStructure()
Switch on stepping according to band structure E(k), for semiconductors.
void SetElectronTransportCut(const double cut)
unsigned int GetNumberOfElectronEndpoints() const
void EnableDebugging()
Switch on debugging messages.
unsigned int GetNumberOfHoleDriftLinePoints(const unsigned int i=0) const
void SetUserHandleInelastic(void(*f)(double x, double y, double z, double t, int type, int level, Medium *m))
Set a user handling procedure, to be called at every inelastic collision.
void SetTimeWindow(const double t0, const double t1)
Define a time interval (only carriers inside the interval are simulated).
Abstract base class for media.
Definition: Medium.hh:11
Visualize drift lines and tracks.
Definition: ViewDrift.hh:15