Garfield++ 5.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 <fstream>
5#include <functional>
6#include <mutex>
7#include <tuple>
8#include <utility>
9#include <vector>
10
11#include "Component.hh"
12#include "Shaper.hh"
13
14class TPad;
15
16namespace Garfield {
17
18/// %Sensor
19
20class Sensor {
21 public:
22 /// Constructor
23 Sensor() = default;
24 /// Destructor
26
27 /// Add a component.
28 void AddComponent(Component* comp);
29 /// Get the number of components attached to the sensor.
30 size_t GetNumberOfComponents() const { return m_components.size(); }
31 /// Retrieve the pointer to a given component.
32 Component* GetComponent(const unsigned int i);
33 /// Activate/deactivate a given component.
34 void EnableComponent(const unsigned int i, const bool on);
35 /// Activate/deactivate use of the magnetic field of a given component.
36 void EnableMagneticField(const unsigned int i, const bool on);
37 /// Does the sensor have a non-zero magnetic field?
38 bool HasMagneticField() const;
39
40 /// Add an electrode.
41 void AddElectrode(Component* comp, const std::string& label);
42 /// Get the number of electrodes attached to the sensor.
43 size_t GetNumberOfElectrodes() const { return m_electrodes.size(); }
44 /// Remove all components, electrodes and reset the sensor.
45 void Clear();
46
47 /// Get the drift field and potential at (x, y, z).
48 void ElectricField(const double x, const double y, const double z, double& ex,
49 double& ey, double& ez, double& v, Medium*& medium,
50 int& status);
51 /// Get the drift field at (x, y, z).
52 void ElectricField(const double x, const double y, const double z, double& ex,
53 double& ey, double& ez, Medium*& medium, int& status);
54
55 /// Get the magnetic field at (x, y, z).
56 void MagneticField(const double x, const double y, const double z, double& bx,
57 double& by, double& bz, int& status);
58
59 /// Get the weighting field at (x, y, z).
60 void WeightingField(const double x, const double y, const double z,
61 double& wx, double& wy, double& wz,
62 const std::string& label);
63 /// Get the weighting potential at (x, y, z).
64 double WeightingPotential(const double x, const double y, const double z,
65 const std::string& label);
66
67 /// Get the delayed weighting potential at (x, y, z).
68 double DelayedWeightingPotential(const double x, const double y,
69 const double z, const double t,
70 const std::string& label);
71
72 /// Get the medium at (x, y, z).
73 Medium* GetMedium(const double x, const double y, const double z);
74
75 /// Switch debugging messages on/off.
76 void EnableDebugging(const bool on = true) { m_debug = on; }
77
78 /// Set the user area to the default.
79 bool SetArea(const bool verbose = false);
80 /// Set the user area explicitly.
81 bool SetArea(const double xmin, const double ymin, const double zmin,
82 const double xmax, const double ymax, const double zmax);
83 /// Return the current user area.
84 bool GetArea(double& xmin, double& ymin, double& zmin, double& xmax,
85 double& ymax, double& zmax);
86 /// Check if a point is inside the user area.
87 bool IsInArea(const double x, const double y, const double z);
88
89 /// Check if a point is inside an active medium and inside the user area.
90 bool IsInside(const double x, const double y, const double z);
91
92 /// Return the voltage range.
93 bool GetVoltageRange(double& vmin, double& vmax);
94
95 /// Start a new event, when computing the average signal over multiple events.
96 void NewSignal() { ++m_nEvents; }
97 /// Reset signals and induced charges of all electrodes.
98 void ClearSignal();
99
100 /** Set the time window and binning for the signal calculation.
101 * \param tstart start time [ns]
102 * \param tstep bin width [ns]
103 * \param nsteps number of bins
104 */
105 void SetTimeWindow(const double tstart, const double tstep,
106 const unsigned int nsteps);
107 /// Retrieve the time window and binning.
108 void GetTimeWindow(double& tstart, double& tstep,
109 unsigned int& nsteps) const {
110 tstart = m_tStart;
111 tstep = m_tStep;
112 nsteps = m_nTimeBins;
113 }
114
115 /// Compute the component of the signal due to the delayed weighting field.
116 void EnableDelayedSignal(const bool on = true) { m_delayedSignal = on; }
117 /// Set the points in time at which to evaluate the delayed weighting field.
118 void SetDelayedSignalTimes(const std::vector<double>& ts);
119 /// Set the number of points to be used when averaging the delayed
120 /// signal vector over a time bin (default: 0).
121 /// The averaging is done with a \f$2\times navg + 1\f$ point
122 /// Newton-Raphson integration.
123 void SetDelayedSignalAveragingOrder(const unsigned int navg) {
124 m_nAvgDelayedSignal = navg;
125 }
126
127 /// Set/override the signal in a given time bin explicitly.
128 void SetSignal(const std::string& label, const unsigned int bin,
129 const double signal);
130 /// Set/override the signal.
131 void SetSignal(const std::string& label,
132 const std::vector<double>& ts,
133 const std::vector<double>& is);
134 /// Retrieve the total signal for a given electrode and time bin.
135 double GetSignal(const std::string& label, const unsigned int bin);
136 /// Retrieve the electron signal for a given electrode and time bin.
137 double GetSignal(const std::string& label, const unsigned int bin,
138 const int comp);
139 /// Retrieve the prompt signal for a given electrode and time bin.
140 double GetPromptSignal(const std::string& label, const unsigned int bin);
141 /// Retrieve the delayed signal for a given electrode and time bin.
142 double GetDelayedSignal(const std::string& label, const unsigned int bin);
143 /// Retrieve the electron signal for a given electrode and time bin.
144 double GetElectronSignal(const std::string& label, const unsigned int bin);
145 /// Retrieve the ion or hole signal for a given electrode and time bin.
146 double GetIonSignal(const std::string& label, const unsigned int bin);
147 /// Retrieve the delayed electron signal for a given electrode and time bin.
148 double GetDelayedElectronSignal(const std::string& label,
149 const unsigned int bin);
150 /// Retrieve the delayed ion/hole signal for a given electrode and time bin.
151 double GetDelayedIonSignal(const std::string& label, const unsigned int bin);
152 /// Calculated using the weighting potentials at the start and end points.
153 double GetInducedCharge(const std::string& label);
154
155 /// Set the function to be used for evaluating the transfer function.
156 void SetTransferFunction(std::function<double(double)>);
157 /// Set the points to be used for interpolating the transfer function.
158 void SetTransferFunction(const std::vector<double>& times,
159 const std::vector<double>& values);
160 /// Set the transfer function using a Shaper object.
161 void SetTransferFunction(Shaper& shaper);
162 /// Evaluate the transfer function at a given time.
163 double GetTransferFunction(const double t);
164 /// Print some information about the presently set transfer function.
166 /// Plot the presently set transfer function.
168 /// Cache integral and FFT of the transfer function
169 /// instead of recomputing it at every call (default: on).
170 void EnableTransferFunctionCache(const bool on = true) {
171 m_cacheTransferFunction = on;
172 }
173 /// Convolute the induced current on a given electrode
174 /// with the transfer function.
175 bool ConvoluteSignal(const std::string& label, const bool fft = false);
176 /// Convolute all induced currents with the transfer function.
177 bool ConvoluteSignals(const bool fft = false);
178 /// Replace the signal on a given electrode by its integral.
179 bool IntegrateSignal(const std::string& label);
180 /// Replace the signals on all electrodes curve by their integrals.
181 bool IntegrateSignals();
182 /// Return whether the signal has been integrated/convoluted.
183 bool IsIntegrated(const std::string& label) const;
184
185 /// Delay the signal and subtract an attenuated copy
186 /// (modelling a constant fraction discriminator).
187 /// \f[
188 /// v_{out} = v_{in}\left(t - t_d\right) - f v_{in}.
189 /// \f]
190 bool DelayAndSubtractFraction(const double td, const double f);
191 /// Set the function to be used for evaluating the noise component.
192 void SetNoiseFunction(double (*f)(double t));
193 /// Add noise to the induced signal.
194 void AddNoise(const bool total = true, const bool electron = false,
195 const bool ion = false);
196 /** Add white noise to the induced signal, given a desired output ENC.
197 * \param label name of the electrode
198 * \param enc Equivalent Noise Charge, in electrons.
199 * \param poisson flag to sample the number of noise pulses from a
200 * Poisson distribution. Otherwise the noise charge in each
201 * bin is sampled from a Gaussian distribution.
202 * \param q0 amplitude of the noise delta pulses (in electrons).
203 */
204 void AddWhiteNoise(const std::string& label, const double enc,
205 const bool poisson = true, const double q0 = 1.);
206 /// Add white noise to the induced signals on all electrodes.
207 void AddWhiteNoise(const double enc, const bool poisson = true,
208 const double q0 = 1.);
209
210 /** Determine the threshold crossings of the current signal curve.
211 * \param thr threshold value
212 * \param label electrode for which to compute the threshold crossings
213 * \param n number of threshold crossings
214 */
215 bool ComputeThresholdCrossings(const double thr, const std::string& label,
216 int& n);
217 /// Get the number of threshold crossings
218 /// (after having called ComputeThresholdCrossings).
220 return m_thresholdCrossings.size();
221 }
222 /** Retrieve the time and type of a given threshold crossing (after having
223 * called ComputeThresholdCrossings.
224 * \param i index
225 * \param time threshold crossing time [ns]
226 * \param level threshold (should correspond to the value requested).
227 * \param rise flag whether the crossing is on a rising or falling slope.
228 */
229 bool GetThresholdCrossing(const unsigned int i, double& time, double& level,
230 bool& rise) const;
231
232 /// Add the signal from a charge-carrier step.
233 void AddSignal(const double q, const double t0, const double t1,
234 const double x0, const double y0, const double z0,
235 const double x1, const double y1, const double z1,
236 const bool integrateWeightingField,
237 const bool useWeightingPotential = false);
238
239 /// Add the signal from a drift line.
240 void AddSignal(const double q, const std::vector<double>& ts,
241 const std::vector<std::array<double, 3> >& xs,
242 const std::vector<std::array<double, 3> >& vs,
243 const std::vector<double>& ns, const int navg,
244 const bool useWeightingPotential = false);
245
246 /// Plot the induced signal.
247 void PlotSignal(const std::string& label, TPad* pad);
248 /// Exporting induced signal to a csv file.
249 void ExportSignal(const std::string& label, const std::string& filename,
250 const bool chargeCariers = false) const;
251
252 /// Add the induced charge from a charge carrier drift between two points.
253 void AddInducedCharge(const double q, const double x0, const double y0,
254 const double z0, const double x1, const double y1,
255 const double z1);
256
257 /// Determine whether a line between two points crosses a wire,
258 /// calls Component::CrossedWire.
259 bool CrossedWire(const double x0, const double y0, const double z0,
260 const double x1, const double y1, const double z1,
261 double& xc, double& yc, double& zc, const bool centre,
262 double& rc);
263 /// Determine whether a point is in the trap radius of a wire.
264 bool InTrapRadius(const double q0, const double x0, const double y0,
265 const double z0, double& xw, double& yw, double& rw);
266 /// Determine whether a line between two points crosses a plane,
267 /// calls Component::CrossedPlane.
268 bool CrossedPlane(const double x0, const double y0, const double z0,
269 const double x1, const double y1, const double z1,
270 double& xc, double& yc, double& zc);
271
272 /// Integrate the electric field flux through a line from
273 /// (x0,y0,z0) to (x1,y1,z1) along a direction (xp,yp,zp).
274 double IntegrateFluxLine(const double x0, const double y0, const double z0,
275 const double x1, const double y1, const double z1,
276 const double xp, const double yp, const double zp,
277 const unsigned int nI, const int isign = 0);
278 // TODO!
279 double GetTotalInducedCharge(const std::string& label);
280
281 double StepSizeHint();
282
283 private:
284 std::string m_className = "Sensor";
285 /// Mutex.
286 std::mutex m_mutex;
287
288 /// Components
289 std::vector<std::tuple<Component*, bool, bool> > m_components;
290
291 struct Electrode {
292 Component* comp;
293 std::string label;
294 std::vector<double> signal;
295 std::vector<double> delayedSignal;
296 std::vector<double> electronSignal;
297 std::vector<double> ionSignal;
298 std::vector<double> delayedElectronSignal;
299 std::vector<double> delayedIonSignal;
300 double charge;
301 bool integrated;
302 };
303 /// Electrodes
304 std::vector<Electrode> m_electrodes;
305
306 // Time window for signals
307 double m_tStart = 0.;
308 double m_tStep = 10.;
309 unsigned int m_nTimeBins = 200;
310 unsigned int m_nEvents = 0;
311 bool m_delayedSignal = false;
312 std::vector<double> m_delayedSignalTimes;
313 unsigned int m_nAvgDelayedSignal = 0;
314
315 // Transfer function
316 std::function<double(double)> m_fTransfer;
317 Shaper* m_shaper = nullptr;
318 std::vector<std::pair<double, double> > m_fTransferTab;
319 bool m_cacheTransferFunction = true;
320 // Integral of the transfer function squared.
321 double m_fTransferSq = -1.;
322 // FFT of the transfer function.
323 std::vector<double> m_fTransferFFT;
324
325 // Noise
326 double (*m_fNoise)(double t) = nullptr;
327
328 std::vector<std::pair<double, bool> > m_thresholdCrossings;
329 double m_thresholdLevel = 0.;
330
331 // User bounding box
332 double m_xMinUser = 0., m_yMinUser = 0., m_zMinUser = 0.;
333 double m_xMaxUser = 0., m_yMaxUser = 0., m_zMaxUser = 0.;
334 bool m_hasUserArea = false;
335
336 // Switch on/off debugging messages
337 bool m_debug = false;
338
339 // Return the current sensor size
340 bool GetBoundingBox(double& xmin, double& ymin, double& zmin, double& xmax,
341 double& ymax, double& zmax);
342
343 void FillSignal(Electrode& electrode, const double q,
344 const std::vector<double>& ts, const std::vector<double>& is,
345 const int navg, const bool delayed = false);
346 void FillBin(Electrode& electrode, const unsigned int bin,
347 const double signal, const bool electron, const bool delayed) {
348 std::lock_guard<std::mutex> guard(m_mutex);
349 electrode.signal[bin] += signal;
350 if (delayed) electrode.delayedSignal[bin] += signal;
351 if (electron) {
352 electrode.electronSignal[bin] += signal;
353 if (delayed) electrode.delayedElectronSignal[bin] += signal;
354 } else {
355 electrode.ionSignal[bin] += signal;
356 if (delayed) electrode.delayedIonSignal[bin] += signal;
357 }
358 }
359
360 void IntegrateSignal(Electrode& electrode);
361 void ConvoluteSignal(Electrode& electrode, const std::vector<double>& tab);
362 bool ConvoluteSignalFFT();
363 bool ConvoluteSignalFFT(const std::string& label);
364 void ConvoluteSignalFFT(Electrode& electrode, const std::vector<double>& tab,
365 const unsigned int nn);
366 // Evaluate the integral over the transfer function squared.
367 double TransferFunctionSq();
368 double InterpolateTransferFunctionTable(const double t) const;
369 void MakeTransferFunctionTable(std::vector<double>& tab);
370 void FFT(std::vector<double>& data, const bool inverse, const int nn);
371};
372} // namespace Garfield
373
374#endif
Abstract base class for components.
Definition Component.hh:13
Abstract base class for media.
Definition Medium.hh:16
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:121
void EnableMagneticField(const unsigned int i, const bool on)
Activate/deactivate use of the magnetic field of a given component.
Definition Sensor.cc:380
double GetElectronSignal(const std::string &label, const unsigned int bin)
Retrieve the electron signal for a given electrode and time bin.
Definition Sensor.cc:906
bool ConvoluteSignal(const std::string &label, const bool fft=false)
Definition Sensor.cc:1179
Medium * GetMedium(const double x, const double y, const double z)
Get the medium at (x, y, z).
Definition Sensor.cc:178
bool GetVoltageRange(double &vmin, double &vmax)
Return the voltage range.
Definition Sensor.cc:442
double GetTotalInducedCharge(const std::string &label)
Definition Sensor.cc:1821
double StepSizeHint()
Definition Sensor.cc:329
void SetDelayedSignalTimes(const std::vector< double > &ts)
Set the points in time at which to evaluate the delayed weighting field.
Definition Sensor.cc:489
void SetTimeWindow(const double tstart, const double tstep, const unsigned int nsteps)
Definition Sensor.cc:869
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:949
void EnableDelayedSignal(const bool on=true)
Compute the component of the signal due to the delayed weighting field.
Definition Sensor.hh:116
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:938
void PlotSignal(const std::string &label, TPad *pad)
Plot the induced signal.
Definition Sensor.cc:1760
bool DelayAndSubtractFraction(const double td, const double f)
Definition Sensor.cc:1380
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:136
double GetTransferFunction(const double t)
Evaluate the transfer function at a given time.
Definition Sensor.cc:1139
void EnableComponent(const unsigned int i, const bool on)
Activate/deactivate a given component.
Definition Sensor.cc:372
~Sensor()
Destructor.
Definition Sensor.hh:25
bool CrossedWire(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:292
void GetTimeWindow(double &tstart, double &tstep, unsigned int &nsteps) const
Retrieve the time window and binning.
Definition Sensor.hh:108
void AddElectrode(Component *comp, const std::string &label)
Add an electrode.
Definition Sensor.cc:396
bool IntegrateSignal(const std::string &label)
Replace the signal on a given electrode by its integral.
Definition Sensor.cc:1341
void AddComponent(Component *comp)
Add a component.
Definition Sensor.cc:355
void SetTransferFunction(std::function< double(double)>)
Set the function to be used for evaluating the transfer function.
Definition Sensor.cc:1043
void PrintTransferFunction()
Print some information about the presently set transfer function.
Definition Sensor.cc:1148
double DelayedWeightingPotential(const double x, const double y, const double z, const double t, const std::string &label)
Get the delayed weighting potential at (x, y, z).
Definition Sensor.cc:164
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:70
double GetSignal(const std::string &label, const unsigned int bin)
Retrieve the total signal for a given electrode and time bin.
Definition Sensor.cc:976
size_t GetNumberOfComponents() const
Get the number of components attached to the sensor.
Definition Sensor.hh:30
void SetNoiseFunction(double(*f)(double t))
Set the function to be used for evaluating the noise component.
Definition Sensor.cc:1398
double GetPromptSignal(const std::string &label, const unsigned int bin)
Retrieve the prompt signal for a given electrode and time bin.
Definition Sensor.cc:1010
bool IntegrateSignals()
Replace the signals on all electrodes curve by their integrals.
Definition Sensor.cc:1331
bool HasMagneticField() const
Does the sensor have a non-zero magnetic field?
Definition Sensor.cc:388
bool ConvoluteSignals(const bool fft=false)
Convolute all induced currents with the transfer function.
Definition Sensor.cc:1202
bool IsInArea(const double x, const double y, const double z)
Check if a point is inside the user area.
Definition Sensor.cc:260
bool CrossedPlane(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, double &xc, double &yc, double &zc)
Definition Sensor.cc:317
double GetInducedCharge(const std::string &label)
Calculated using the weighting potentials at the start and end points.
Definition Sensor.cc:1033
void AddNoise(const bool total=true, const bool electron=false, const bool ion=false)
Add noise to the induced signal.
Definition Sensor.cc:1406
size_t GetNumberOfElectrodes() const
Get the number of electrodes attached to the sensor.
Definition Sensor.hh:43
double IntegrateFluxLine(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, const double xp, const double yp, const double zp, const unsigned int nI, const int isign=0)
Definition Sensor.cc:340
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:152
Component * GetComponent(const unsigned int i)
Retrieve the pointer to a given component.
Definition Sensor.cc:364
void AddWhiteNoise(const std::string &label, const double enc, const bool poisson=true, const double q0=1.)
Definition Sensor.cc:1425
bool ComputeThresholdCrossings(const double thr, const std::string &label, int &n)
Definition Sensor.cc:1536
void Clear()
Remove all components, electrodes and reset the sensor.
Definition Sensor.cc:426
bool SetArea(const bool verbose=false)
Set the user area to the default.
Definition Sensor.cc:187
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:498
bool GetThresholdCrossing(const unsigned int i, double &time, double &level, bool &rise) const
Definition Sensor.cc:1650
size_t GetNumberOfThresholdCrossings() const
Definition Sensor.hh:219
bool IsInside(const double x, const double y, const double z)
Check if a point is inside an active medium and inside the user area.
Definition Sensor.cc:282
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:927
void EnableTransferFunctionCache(const bool on=true)
Definition Sensor.hh:170
void ClearSignal()
Reset signals and induced charges of all electrodes.
Definition Sensor.cc:475
double GetDelayedSignal(const std::string &label, const unsigned int bin)
Retrieve the delayed signal for a given electrode and time bin.
Definition Sensor.cc:1022
void ExportSignal(const std::string &label, const std::string &filename, const bool chargeCariers=false) const
Exporting induced signal to a csv file.
Definition Sensor.cc:1771
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:845
void PlotTransferFunction()
Plot the presently set transfer function.
Definition Sensor.cc:1085
bool InTrapRadius(const double q0, const double x0, const double y0, const double z0, double &xw, double &yw, double &rw)
Determine whether a point is in the trap radius of a wire.
Definition Sensor.cc:306
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:917
void EnableDebugging(const bool on=true)
Switch debugging messages on/off.
Definition Sensor.hh:76
void SetDelayedSignalAveragingOrder(const unsigned int navg)
Definition Sensor.hh:123
void NewSignal()
Start a new event, when computing the average signal over multiple events.
Definition Sensor.hh:96
bool GetArea(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Return the current user area.
Definition Sensor.cc:234
bool IsIntegrated(const std::string &label) const
Return whether the signal has been integrated/convoluted.
Definition Sensor.cc:1373
Class for signal processing.
Definition Shaper.hh:11