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