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