Garfield 0.3
Toolkit for the detailed simulation of particle detectors based on ionization measurement in gases and semiconductors
Loading...
Searching...
No Matches
Sensor.hh
Go to the documentation of this file.
1// Include this header if we're compiling with the GPU or this is the first time
2// without
3#if defined(__GPUCOMPILE__) || !defined(G_SENSOR_H)
4
5#if !defined(__GPUCOMPILE__) && !defined(G_SENSOR_H)
6#define G_SENSOR_H
7#endif
8
10
11#ifdef __GPUCOMPILE__
12
13#else
14#include <array>
15#include <functional>
16#include <mutex>
17#include <tuple>
18#include <utility>
19#include <vector>
20
21#include "Garfield/Component.hh"
22#endif
23
24class TPad;
25
26namespace Garfield {
27
28#if defined(__GPUCONST__)
29#undef __GPUCONST__
30#endif
31
32// setup class names depending on if this is compiling the GPU static version or
33// not
34#ifdef __GPUCOMPILE__
35#define __GPUCONST__ const
36#else
37#define __GPUCONST__
38class SensorGPU;
39class Shaper;
40#endif
41
43
44class GARFIELD_CLASS_NAME(Sensor) {
45 public:
47 GARFIELD_CLASS_NAME(Sensor)() = default;
49 ~GARFIELD_CLASS_NAME(Sensor)() = default;
50
51#ifndef __GPUCOMPILE__
53 Sensor(Component* comp);
55 void AddComponent(Component* comp);
57 size_t GetNumberOfComponents() const { return m_components.size(); }
59 Component* GetComponent(const unsigned int i);
61 void EnableComponent(const unsigned int i, const bool on);
63 void EnableMagneticField(const unsigned int i, const bool on);
65 bool HasMagneticField() const;
66
68 void AddElectrode(Component* comp, const std::string& label);
70 size_t GetNumberOfElectrodes() const { return m_electrodes.size(); }
72 void ClearElectrodes();
74 void Clear();
75
77 void ElectricField(const double x, const double y, const double z, double& ex,
78 double& ey, double& ez, double& v, Medium*& medium,
79 int& status);
80#endif
83 void ElectricField(const double x, const double y, const double z, double& ex,
84 double& ey, double& ez,
85 GARFIELD_CLASS_NAME(Medium) * &medium,
86 int& status) __GPUCONST__;
87
88#ifndef __GPUCOMPILE__
90 void MagneticField(const double x, const double y, const double z, double& bx,
91 double& by, double& bz, int& status);
92
94 void WeightingField(const double x, const double y, const double z,
95 double& wx, double& wy, double& wz,
96 const std::string& label);
98 double WeightingPotential(const double x, const double y, const double z,
99 const std::string& label);
100
102 double DelayedWeightingPotential(const double x, const double y,
103 const double z, const double t,
104 const std::string& label);
105
107 Medium* GetMedium(const double x, const double y, const double z);
108
110 void EnableDebugging(const bool on = true) { m_debug = on; }
111
113 bool SetArea(const bool verbose = false);
115 bool SetArea(const double xmin, const double ymin, const double zmin,
116 const double xmax, const double ymax, const double zmax);
118 bool GetArea(double& xmin, double& ymin, double& zmin, double& xmax,
119 double& ymax, double& zmax);
120#endif
123 bool IsInArea(const double x, const double y, const double z) __GPUCONST__;
124
125#ifndef __GPUCOMPILE__
127 bool IsInside(const double x, const double y, const double z);
128
130 bool GetVoltageRange(double& vmin, double& vmax);
131
133 void NewSignal() { ++m_nEvents; }
135 void ClearSignal();
136#else
138 __device__ void AddSignal(const double q, const double t0, const double t1,
139 const double x0, const double y0, const double z0,
140 const double x1, const double y1, const double z1,
141 const bool integrateWeightingField,
142 const bool useWeightingPotential,
143 const int particle_idx);
144#endif
145
146#ifndef __GPUCOMPILE__
152 void SetTimeWindow(const double tstart, const double tstep,
153 const unsigned int nsteps);
155 void GetTimeWindow(double& tstart, double& tstep,
156 unsigned int& nsteps) const {
157 tstart = m_tStart;
158 tstep = m_tStep;
159 nsteps = m_nTimeBins;
160 }
161
163 void EnableDelayedSignal(const bool on = true) { m_delayedSignal = on; }
165 void SetDelayedSignalTimes(const std::vector<double>& ts);
170 void SetDelayedSignalAveragingOrder(const unsigned int navg) {
171 m_nAvgDelayedSignal = navg;
172 }
173
175 void SetSignal(const std::string& label, const unsigned int bin,
176 const double signal);
178 void SetSignal(const std::string& label, const std::vector<double>& ts,
179 const std::vector<double>& is);
181 double GetSignal(const std::string& label, const unsigned int bin);
183 double GetSignal(const std::string& label, const unsigned int bin,
184 const int comp);
186 double GetPromptSignal(const std::string& label, const unsigned int bin);
188 double GetDelayedSignal(const std::string& label, const unsigned int bin);
190 double GetElectronSignal(const std::string& label, const unsigned int bin);
192 double GetIonSignal(const std::string& label, const unsigned int bin);
194 double GetDelayedElectronSignal(const std::string& label,
195 const unsigned int bin);
197 double GetDelayedIonSignal(const std::string& label, const unsigned int bin);
199 double GetInducedCharge(const std::string& label);
200
202 void SetTransferFunction(std::function<double(double)>);
204 void SetTransferFunction(const std::vector<double>& times,
205 const std::vector<double>& values);
207 void SetTransferFunction(Shaper& shaper);
209 double GetTransferFunction(const double t);
211 void PrintTransferFunction();
213 void PlotTransferFunction();
216 void EnableTransferFunctionCache(const bool on = true) {
217 m_cacheTransferFunction = on;
218 }
221 bool ConvoluteSignal(const std::string& label, const bool fft = false);
223 bool ConvoluteSignals(const bool fft = false);
225 bool IntegrateSignal(const std::string& label);
227 bool IntegrateSignals();
229 bool IsIntegrated(const std::string& label) const;
230
236 bool DelayAndSubtractFraction(const double td, const double f);
238 void SetNoiseFunction(double (*f)(double t));
240 void AddNoise(const bool total = true, const bool electron = false,
241 const bool ion = false);
250 void AddWhiteNoise(const std::string& label, const double enc,
251 const bool poisson = true, const double q0 = 1.);
253 void AddWhiteNoise(const double enc, const bool poisson = true,
254 const double q0 = 1.);
255
261 bool ComputeThresholdCrossings(const double thr, const std::string& label,
262 int& n);
265 size_t GetNumberOfThresholdCrossings() const {
266 return m_thresholdCrossings.size();
267 }
275 bool GetThresholdCrossing(const unsigned int i, double& time, double& level,
276 bool& rise) const;
277
280 void AddSignalWeightingPotential(
281 const double q, const std::vector<double>& ts,
282 const std::vector<std::array<double, 3> >& xs);
285 void AddSignalWeightingPotential(
286 const double q, const std::vector<double>& ts,
287 const std::vector<std::array<double, 3> >& xs,
288 const std::vector<double>& qs);
291 void AddSignalWeightingField(const double q, const std::vector<double>& ts,
292 const std::vector<std::array<double, 3> >& xs,
293 const bool integrateWeightingField);
297 void AddSignalWeightingField(const double q, const std::vector<double>& ts,
298 const std::vector<std::array<double, 3> >& xs,
299 const std::vector<std::array<double, 3> >& vs,
300 const std::vector<double>& ns, const int navg);
301
303 void PlotSignal(const std::string& label, TPad* pad,
304 const std::string optTotal = "t",
305 const std::string optPrompt = "",
306 const std::string optDelayed = "");
308 void ExportSignal(const std::string& label, const std::string& filename,
309 const bool chargeCariers = false) const;
310
312 void AddInducedCharge(const double q, const double x0, const double y0,
313 const double z0, const double x1, const double y1,
314 const double z1);
315
318 bool CrossedWire(const double x0, const double y0, const double z0,
319 const double x1, const double y1, const double z1,
320 double& xc, double& yc, double& zc, const bool centre,
321 double& rc);
323 bool InTrapRadius(const double q0, const double x0, const double y0,
324 const double z0, double& xw, double& yw, double& rw);
327 bool CrossedPlane(const double x0, const double y0, const double z0,
328 const double x1, const double y1, const double z1,
329 double& xc, double& yc, double& zc);
330
333 double IntegrateFluxLine(const double x0, const double y0, const double z0,
334 const double x1, const double y1, const double z1,
335 const double xp, const double yp, const double zp,
336 const unsigned int nI, const int isign = 0);
337 // TODO!
338 double GetTotalInducedCharge(const std::string& label);
339
340 double StepSizeHint();
341
343 double CreateGPUTransferObject(SensorGPU*& sensor_gpu);
344#if USEGPU
346 void TransferGPUElectrodeSignals(SensorGPU*& sensor_gpu);
347#endif
348
349 private:
350 std::string m_className = "Sensor";
352 std::mutex m_mutex;
353#endif
354
356#ifdef __GPUCOMPILE__
357 ComponentGPU** m_components = nullptr;
358 size_t m_numComponents;
359 friend class Sensor;
360#else
361 std::vector<std::tuple<Component*, bool, bool> > m_components;
362#endif
363
364#ifndef __GPUCOMPILE__
365 struct Electrode {
366 Component* comp;
367 std::string label;
368 std::vector<double> signal;
369 std::vector<double> delayedSignal;
370 std::vector<double> electronSignal;
371 std::vector<double> ionSignal;
372 std::vector<double> delayedElectronSignal;
373 std::vector<double> delayedIonSignal;
374 double charge;
375 bool integrated;
376 };
378 std::vector<Electrode> m_electrodes;
379#else
380 struct ElectrodeGPU {
381 ComponentGPU* comp;
382 int label;
383 double* signal;
384 };
385
386 ElectrodeGPU* m_electrodes = nullptr;
387 size_t m_numElectrodes;
388#endif
389
390 // Time window for signals
391 double m_tStart = 0.;
392 double m_tStep = 10.;
393 unsigned int m_nTimeBins = 200;
394 unsigned int m_nEvents = 0;
395#ifndef __GPUCOMPILE__
396 bool m_delayedSignal = false;
397 std::vector<double> m_delayedSignalTimes;
398 unsigned int m_nAvgDelayedSignal = 0;
399
400 // Transfer function
401 std::function<double(double)> m_fTransfer;
402 Shaper* m_shaper = nullptr;
403 std::vector<std::pair<double, double> > m_fTransferTab;
404 bool m_cacheTransferFunction = true;
405 // Integral of the transfer function squared.
406 double m_fTransferSq = -1.;
407 // FFT of the transfer function.
408 std::vector<double> m_fTransferFFT;
409
410 // Noise
411 double (*m_fNoise)(double t) = nullptr;
412
413 std::vector<std::pair<double, bool> > m_thresholdCrossings;
414 double m_thresholdLevel = 0.;
415#endif
416
417 // User bounding box
418 double m_xMinUser = 0., m_yMinUser = 0., m_zMinUser = 0.;
419 double m_xMaxUser = 0., m_yMaxUser = 0., m_zMaxUser = 0.;
420 bool m_hasUserArea = false;
421
422#ifndef __GPUCOMPILE__
423 // Switch on/off debugging messages
424 bool m_debug = false;
425
426 // Return the current sensor size
427 bool GetBoundingBox(double& xmin, double& ymin, double& zmin, double& xmax,
428 double& ymax, double& zmax);
429
430 void FillSignal(Electrode& electrode, const double q,
431 const std::vector<double>& ts, const std::vector<double>& is,
432 const int navg, const bool delayed = false);
433 void FillBin(Electrode& electrode, const unsigned int bin,
434 const double signal, const bool electron, const bool delayed) {
435 std::lock_guard<std::mutex> guard(m_mutex);
436 electrode.signal[bin] += signal;
437 if (delayed) electrode.delayedSignal[bin] += signal;
438 if (electron) {
439 electrode.electronSignal[bin] += signal;
440 if (delayed) electrode.delayedElectronSignal[bin] += signal;
441 } else {
442 electrode.ionSignal[bin] += signal;
443 if (delayed) electrode.delayedIonSignal[bin] += signal;
444 }
445 }
446#else
447 __device__ void FillBin(ElectrodeGPU& electrode, const unsigned int bin,
448 const double signal, const bool electron,
449 const bool delayed, const int particle_idx);
450#endif
451
452#ifndef __GPUCOMPILE__
453 void IntegrateSignal(Electrode& electrode);
454 void ConvoluteSignal(Electrode& electrode, const std::vector<double>& tab);
455 bool ConvoluteSignalFFT();
456 bool ConvoluteSignalFFT(const std::string& label);
457 void ConvoluteSignalFFT(Electrode& electrode, const std::vector<double>& tab,
458 const unsigned int nn);
459 // Evaluate the integral over the transfer function squared.
460 double TransferFunctionSq();
461 double InterpolateTransferFunctionTable(const double t) const;
462 void MakeTransferFunctionTable(std::vector<double>& tab);
463 void FFT(std::vector<double>& data, const bool inverse, const int nn);
464#endif
465};
466} // namespace Garfield
467
468#undef SENSORCLASS
469#endif
#define GARFIELD_CLASS_NAME(name)
#define __DEVICE__
#define __GPUCONST__
Definition Sensor.hh:37
#define __device__
Definition Vector.hh:12