Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Sensor.hh
Go to the documentation of this file.
1#ifndef G_SENSOR_H
2#define G_SENSOR_H
3
4#include <vector>
5#include <utility>
6
7#include "ComponentBase.hh"
8#include "Shaper.hh"
9
10namespace Garfield {
11
12/// %Sensor
13
14class Sensor {
15 public:
16 /// Constructor
17 Sensor() = default;
18 /// Destructor
20
21 /// Add a component.
22 void AddComponent(ComponentBase* comp);
23 /// Get the number of components attached to the sensor.
24 unsigned int GetNumberOfComponents() const { return m_components.size(); }
25 /// Retrieve the pointer to a given component.
26 ComponentBase* GetComponent(const unsigned int i);
27
28 /// Add an electrode.
29 void AddElectrode(ComponentBase* comp, const std::string& label);
30 /// Get the number of electrodes attached to the sensor.
31 unsigned int GetNumberOfElectrodes() const { return m_electrodes.size(); }
32 /// Remove all components, electrodes and reset the sensor.
33 void Clear();
34
35 /// Get the drift field and potential at (x, y, z).
36 void ElectricField(const double x, const double y, const double z, double& ex,
37 double& ey, double& ez, double& v, Medium*& medium,
38 int& status);
39 /// Get the drift field at (x, y, z).
40 void ElectricField(const double x, const double y, const double z, double& ex,
41 double& ey, double& ez, Medium*& medium, int& status);
42
43 /// Get the magnetic field at (x, y, z).
44 void MagneticField(const double x, const double y, const double z, double& bx,
45 double& by, double& bz, int& status);
46
47 /// Get the weighting field at (x, y, z).
48 void WeightingField(const double x, const double y, const double z,
49 double& wx, double& wy, double& wz,
50 const std::string& label);
51 /// Get the weighting potential at (x, y, z).
52 double WeightingPotential(const double x, const double y, const double z,
53 const std::string& label);
54
55 /// Get the medium at (x, y, z).
56 bool GetMedium(const double x, const double y, const double z,
57 Medium*& medium);
58
59 /// Switch debugging messages on/off.
60 void EnableDebugging(const bool on = true) { m_debug = on; }
61
62 /// Set the user area to the default.
63 bool SetArea();
64 /// Set the user area explicitly.
65 bool SetArea(const double xmin, const double ymin, const double zmin,
66 const double xmax, const double ymax, const double zmax);
67 /// Return the current user area.
68 bool GetArea(double& xmin, double& ymin, double& zmin, double& xmax,
69 double& ymax, double& zmax);
70 /// Check if a point is inside the user area.
71 bool IsInArea(const double x, const double y, const double z);
72
73 /// Return the voltage range.
74 bool GetVoltageRange(double& vmin, double& vmax);
75
76 /// Start a new event, when computing the average signal over multiple events.
77 void NewSignal() { ++m_nEvents; }
78 /// Reset signals and induced charges of all electrodes.
79 void ClearSignal();
80
81 /** Set the time window and binning for the signal calculation.
82 * \param tstart start time [ns]
83 * \param tstep bin width [ns]
84 * \param nsteps number of bins
85 */
86 void SetTimeWindow(const double tstart, const double tstep,
87 const unsigned int nsteps);
88 /// Retrieve the time window and binning.
89 void GetTimeWindow(double& tstart, double& tstep,
90 unsigned int& nsteps) const {
91 tstart = m_tStart;
92 tstep = m_tStep;
93 nsteps = m_nTimeBins;
94 }
95
96 /// Compute the component of the signal due to the delayed weighting field.
97 void EnableDelayedSignal(const bool on = true) { m_delayedSignal = on; }
98 /// Set the points in time at which to evaluate the delayed weighting field.
99 void SetDelayedSignalTimes(const std::vector<double>& ts);
100 /// Set the number of points to be used when averaging the delayed
101 /// signal vector over a time bin (default: 0).
102 /// The averaging is done with a \f$2\times navg + 1\f$ point
103 /// Newton-Raphson integration.
104 void SetDelayedSignalAveragingOrder(const unsigned int navg) {
105 m_nAvgDelayedSignal = navg;
106 }
107
108 /// Set/override the signal in a given time bin explicitly.
109 void SetSignal(const std::string& label, const unsigned int bin,
110 const double signal);
111 /// Retrieve the total signal for a given electrode and time bin.
112 double GetSignal(const std::string& label, const unsigned int bin);
113 /// Retrieve the electron signal for a given electrode and time bin.
114 double GetElectronSignal(const std::string& label, const unsigned int bin);
115 /// Retrieve the ion or hole signal for a given electrode and time bin.
116 double GetIonSignal(const std::string& label, const unsigned int bin);
117 /// Retrieve the delayed electron signal for a given electrode and time bin.
118 double GetDelayedElectronSignal(const std::string& label, const unsigned int bin);
119 /// Retrieve the delayed ion/hole signal for a given electrode and time bin.
120 double GetDelayedIonSignal(const std::string& label, const unsigned int bin);
121 /// Retrieve the total induced charge for a given electrode,
122 /// calculated using the weighting potentials at the start and end points.
123 double GetInducedCharge(const std::string& label);
124 /// Set the function to be used for evaluating the transfer function.
125 void SetTransferFunction(double (*f)(double t));
126 /// Set the points to be used for interpolating the transfer function.
127 void SetTransferFunction(const std::vector<double>& times,
128 const std::vector<double>& values);
129 /// Set the transfer function using a Shaper object.
130 void SetTransferFunction(Shaper &shaper);
131 /// Evaluate the transfer function at a given time.
132 double GetTransferFunction(const double t);
133 /// Cache integral and FFT of the transfer function
134 /// instead of recomputing it at every call (default: on).
135 void EnableTransferFunctionCache(const bool on = true) {
136 m_cacheTransferFunction = on;
137 }
138 /// Convolute the induced current with the transfer function.
139 bool ConvoluteSignal(const bool fft = false);
140 /// Replace the current signal curve by its integral.
141 bool IntegrateSignal();
142 /// Return whether the signal has been integrated/convoluted.
143 bool IsIntegrated() const { return m_integrated; }
144
145 /// Delay the signal and subtract an attenuated copy
146 /// (modelling a constant fraction discriminator).
147 /// \f[
148 /// v_{out} = v_{in}\left(t - t_d\right) - f v_{in}.
149 /// \f]
150 bool DelayAndSubtractFraction(const double td, const double f);
151 /// Set the function to be used for evaluating the noise component.
152 void SetNoiseFunction(double (*f)(double t));
153 /// Add noise to the induced signal.
154 void AddNoise(const bool total = true, const bool electron = false,
155 const bool ion = false);
156 /** Add white noise to the induced signal, given a desired output ENC.
157 * \param enc Equivalent Noise Charge, in electrons.
158 * \param poisson flag to sample the number of noise pulses from a
159 * Poisson distribution. Otherwise the noise charge in each
160 * bin is sampled from a Gaussian distribution.
161 * \param q0 amplitude of the noise delta pulses (in electrons).
162 */
163 void AddWhiteNoise(const double enc, const bool poisson = true,
164 const double q0 = 1.);
165 /** Determine the threshold crossings of the current signal curve.
166 * \param thr threshold value
167 * \param label electrode for which to compute the threshold crossings
168 * \param n number of threshold crossings
169 */
170 bool ComputeThresholdCrossings(const double thr, const std::string& label,
171 int& n);
172 /// Get the number of threshold crossings
173 /// (after having called ComputeThresholdCrossings).
174 unsigned int GetNumberOfThresholdCrossings() const {
175 return m_thresholdCrossings.size();
176 }
177 /** Retrieve the time and type of a given threshold crossing (after having
178 * called ComputeThresholdCrossings.
179 * \param i index
180 * \param time threshold crossing time [ns]
181 * \param level threshold (should correspond to the value requested).
182 * \param rise flag whether the crossing is on a rising or falling slope.
183 */
184 bool GetThresholdCrossing(const unsigned int i, double& time, double& level,
185 bool& rise) const;
186
187 /// Add the signal from a charge-carrier step.
188 void AddSignal(const double q, const double t0, const double t1,
189 const double x0, const double y0, const double z0,
190 const double x1, const double y1, const double z1,
191 const bool integrateWeightingField,
192 const bool useWeightingPotential = false);
193 /// Add the signal from a drift line.
194 void AddSignal(const double q, const std::vector<double>& ts,
195 const std::vector<std::array<double, 3> >& xs,
196 const std::vector<std::array<double, 3> >& vs,
197 const std::vector<double>& ns, const int navg);
198 /// Add the induced charge from a charge carrier drift between two points.
199 void AddInducedCharge(const double q, const double x0, const double y0,
200 const double z0, const double x1, const double y1,
201 const double z1);
202
203 /// Determine whether a line between two points has crossed a wire,
204 /// calls ComponentBase::IsWireCrossed.
205 bool IsWireCrossed(const double x0, const double y0, const double z0,
206 const double x1, const double y1, const double z1,
207 double& xc, double& yc, double& zc,
208 const bool centre, double& rc);
209 bool IsInTrapRadius(const double q0, const double x0, const double y0,
210 const double z0, double& xw, double& yw, double& rw);
211
212 private:
213 std::string m_className = "Sensor";
214
215 /// Components
216 std::vector<ComponentBase*> m_components;
217 ComponentBase* m_lastComponent = nullptr;
218
219 struct Electrode {
220 ComponentBase* comp;
221 std::string label;
222 std::vector<double> signal;
223 std::vector<double> electronsignal;
224 std::vector<double> ionsignal;
225 std::vector<double> delayedElectronSignal;
226 std::vector<double> delayedIonSignal;
227 double charge;
228 };
229 /// Electrodes
230 std::vector<Electrode> m_electrodes;
231
232 // Time window for signals
233 unsigned int m_nTimeBins = 200;
234 double m_tStart = 0.;
235 double m_tStep = 10.;
236 unsigned int m_nEvents = 0;
237 bool m_delayedSignal = false;
238 std::vector<double> m_delayedSignalTimes;
239 unsigned int m_nAvgDelayedSignal = 0;
240
241 // Transfer function
242 double (*m_fTransfer)(double t) = nullptr;
243 Shaper* m_shaper = nullptr;
244 std::vector<std::pair<double, double> > m_fTransferTab;
245 bool m_cacheTransferFunction = true;
246 // Integral of the transfer function squared.
247 double m_fTransferSq = -1.;
248 // FFT of the transfer function.
249 std::vector<double> m_fTransferFFT;
250 // Flag whether the signals have been convoluted/integrated.
251 bool m_integrated = false;
252
253 // Noise
254 double (*m_fNoise)(double t) = nullptr;
255
256 std::vector<std::pair<double, bool> > m_thresholdCrossings;
257 double m_thresholdLevel = 0.;
258
259 // User bounding box
260 bool m_hasUserArea = false;
261 double m_xMinUser = 0., m_yMinUser = 0., m_zMinUser = 0.;
262 double m_xMaxUser = 0., m_yMaxUser = 0., m_zMaxUser = 0.;
263
264 // Switch on/off debugging messages
265 bool m_debug = false;
266
267 // Return the current sensor size
268 bool GetBoundingBox(double& xmin, double& ymin, double& zmin, double& xmax,
269 double& ymax, double& zmax);
270
271 void FillSignal(Electrode& electrode, const double q,
272 const std::vector<double>& ts,
273 const std::vector<double>& is, const int navg,
274 const bool delayed = false);
275 void FillBin(Electrode& electrode, const unsigned int bin,
276 const double signal, const bool electron, const bool delayed) {
277 electrode.signal[bin] += signal;
278 if (electron) {
279 electrode.electronsignal[bin] += signal;
280 if (delayed) electrode.delayedElectronSignal[bin] += signal;
281 } else {
282 electrode.ionsignal[bin] += signal;
283 if (delayed) electrode.delayedIonSignal[bin] += signal;
284 }
285 }
286 // Evaluate the integral over the transfer function squared.
287 double TransferFunctionSq();
288 double InterpolateTransferFunctionTable(const double t) const;
289 bool ConvoluteSignalFFT();
290 void FFT(std::vector<double>& data, const bool inverse, const int nn);
291};
292}
293
294#endif
Abstract base class for components.
Abstract base class for media.
Definition: Medium.hh:13
void MagneticField(const double x, const double y, const double z, double &bx, double &by, double &bz, int &status)
Get the magnetic field at (x, y, z).
Definition: Sensor.cc:124
bool IsIntegrated() const
Return whether the signal has been integrated/convoluted.
Definition: Sensor.hh:143
double GetElectronSignal(const std::string &label, const unsigned int bin)
Retrieve the electron signal for a given electrode and time bin.
Definition: Sensor.cc:733
bool GetVoltageRange(double &vmin, double &vmax)
Return the voltage range.
Definition: Sensor.cc:355
void AddWhiteNoise(const double enc, const bool poisson=true, const double q0=1.)
Definition: Sensor.cc:1036
void SetDelayedSignalTimes(const std::vector< double > &ts)
Set the points in time at which to evaluate the delayed weighting field.
Definition: Sensor.cc:400
void SetTimeWindow(const double tstart, const double tstep, const unsigned int nsteps)
Definition: Sensor.cc:700
bool IntegrateSignal()
Replace the current signal curve by its integral.
Definition: Sensor.cc:968
void SetSignal(const std::string &label, const unsigned int bin, const double signal)
Set/override the signal in a given time bin explicitly.
Definition: Sensor.cc:776
void EnableDelayedSignal(const bool on=true)
Compute the component of the signal due to the delayed weighting field.
Definition: Sensor.hh:97
double GetDelayedIonSignal(const std::string &label, const unsigned int bin)
Retrieve the delayed ion/hole signal for a given electrode and time bin.
Definition: Sensor.cc:765
bool IsInTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yw, double &rw)
Definition: Sensor.cc:293
bool DelayAndSubtractFraction(const double td, const double f)
Definition: Sensor.cc:990
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
Get the weighting field at (x, y, z).
Definition: Sensor.cc:138
double GetTransferFunction(const double t)
Evaluate the transfer function at a given time.
Definition: Sensor.cc:868
~Sensor()
Destructor.
Definition: Sensor.hh:19
void GetTimeWindow(double &tstart, double &tstep, unsigned int &nsteps) const
Retrieve the time window and binning.
Definition: Sensor.hh:89
unsigned int GetNumberOfElectrodes() const
Get the number of electrodes attached to the sensor.
Definition: Sensor.hh:31
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&medium, int &status)
Get the drift field and potential at (x, y, z).
Definition: Sensor.cc:75
bool SetArea()
Set the user area to the default.
Definition: Sensor.cc:189
double GetSignal(const std::string &label, const unsigned int bin)
Retrieve the total signal for a given electrode and time bin.
Definition: Sensor.cc:788
void SetNoiseFunction(double(*f)(double t))
Set the function to be used for evaluating the noise component.
Definition: Sensor.cc:1009
bool IsInArea(const double x, const double y, const double z)
Check if a point is inside the user area.
Definition: Sensor.cc:258
void AddElectrode(ComponentBase *comp, const std::string &label)
Add an electrode.
Definition: Sensor.cc:310
double GetInducedCharge(const std::string &label)
Definition: Sensor.cc:798
void AddNoise(const bool total=true, const bool electron=false, const bool ion=false)
Add noise to the induced signal.
Definition: Sensor.cc:1017
double WeightingPotential(const double x, const double y, const double z, const std::string &label)
Get the weighting potential at (x, y, z).
Definition: Sensor.cc:154
bool ComputeThresholdCrossings(const double thr, const std::string &label, int &n)
Definition: Sensor.cc:1102
bool GetMedium(const double x, const double y, const double z, Medium *&medium)
Get the medium at (x, y, z).
Definition: Sensor.cc:166
void Clear()
Remove all components, electrodes and reset the sensor.
Definition: Sensor.cc:339
void AddSignal(const double q, const double t0, const double t1, const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, const bool integrateWeightingField, const bool useWeightingPotential=false)
Add the signal from a charge-carrier step.
Definition: Sensor.cc:409
bool ConvoluteSignal(const bool fft=false)
Convolute the induced current with the transfer function.
Definition: Sensor.cc:877
void SetTransferFunction(double(*f)(double t))
Set the function to be used for evaluating the transfer function.
Definition: Sensor.cc:808
bool GetThresholdCrossing(const unsigned int i, double &time, double &level, bool &rise) const
Definition: Sensor.cc:1216
void AddComponent(ComponentBase *comp)
Add a component.
Definition: Sensor.cc:301
unsigned int GetNumberOfThresholdCrossings() const
Definition: Sensor.hh:174
Sensor()=default
Constructor.
double GetDelayedElectronSignal(const std::string &label, const unsigned int bin)
Retrieve the delayed electron signal for a given electrode and time bin.
Definition: Sensor.cc:754
void EnableTransferFunctionCache(const bool on=true)
Definition: Sensor.hh:135
bool IsWireCrossed(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, double &xc, double &yc, double &zc, const bool centre, double &rc)
Definition: Sensor.cc:280
void ClearSignal()
Reset signals and induced charges of all electrodes.
Definition: Sensor.cc:387
void AddInducedCharge(const double q, const double x0, const double y0, const double z0, const double x1, const double y1, const double z1)
Add the induced charge from a charge carrier drift between two points.
Definition: Sensor.cc:678
unsigned int GetNumberOfComponents() const
Get the number of components attached to the sensor.
Definition: Sensor.hh:24
double GetIonSignal(const std::string &label, const unsigned int bin)
Retrieve the ion or hole signal for a given electrode and time bin.
Definition: Sensor.cc:744
void EnableDebugging(const bool on=true)
Switch debugging messages on/off.
Definition: Sensor.hh:60
void SetDelayedSignalAveragingOrder(const unsigned int navg)
Definition: Sensor.hh:104
void NewSignal()
Start a new event, when computing the average signal over multiple events.
Definition: Sensor.hh:77
bool GetArea(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Return the current user area.
Definition: Sensor.cc:232
ComponentBase * GetComponent(const unsigned int i)
Retrieve the pointer to a given component.
Definition: Sensor.cc:67
Class for signal processing.
Definition: Shaper.hh:11