Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
example.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <cmath>
3
4#include <TApplication.h>
5#include <TCanvas.h>
6
12#include "Garfield/Sensor.hh"
13#include "Garfield/TrackHeed.hh"
15#include "Garfield/Plotting.hh"
16
17using namespace Garfield;
18
19int main(int argc, char * argv[]){
20
21 TApplication app("app", &argc, argv);
22 plottingEngine.SetDefaultStyle();
23
24 // Set the gas mixture.
25 MediumMagboltz gas("ar", 90., "c4h10", 10.);
26
27 // Build the Micromegas geometry.
28 // We use separate components for drift and amplification regions.
31 cmpD.SetMedium(&gas);
32 cmpA.SetMedium(&gas);
33 // Set the magnetic field [Tesla].
34 constexpr double bfield = 2.;
35 cmpD.SetMagneticField(0, 0, bfield);
36 cmpA.SetMagneticField(0, 0, bfield);
37
38 // 100 um amplification gap.
39 constexpr double yMesh = 0.01;
40 constexpr double vMesh = -500.;
41 cmpA.AddPlaneY(yMesh, vMesh, "mesh");
42 cmpA.AddPlaneY(0., 0., "bottom");
43
44 // 3 mm drift gap.
45 constexpr double yDrift = yMesh + 0.3;
46 constexpr double vDrift = -3000.;
47 cmpD.AddPlaneY(yDrift, vDrift, "top");
48 cmpD.AddPlaneY(yMesh, vMesh, "mesh");
49
50 // We place three strips along z direction on the anode plane
51 // in order to be able to resolve the avalanche signal.
52 // Strip pitch [cm].
53 constexpr double pitch = 0.07;
54 // Distance between two strips [cm].
55 constexpr double interstrip = 0.01;
56 // Half-width of a strip.
57 constexpr double hw = 0.5 * (pitch - interstrip);
58 const double xStrip1 = hw;
59 cmpA.AddStripOnPlaneY('z', 0., xStrip1 - hw, xStrip1 + hw, "strip1");
60 const double xStrip2 = xStrip1 + pitch;
61 cmpA.AddStripOnPlaneY('z', 0., xStrip2 - hw, xStrip2 + hw, "strip2");
62 const double xStrip3 = xStrip2 + pitch;
63 cmpA.AddStripOnPlaneY('z', 0., xStrip3 - hw, xStrip3 + hw, "strip3");
64
65 // Assemble a sensor.
66 Sensor sensor;
67 sensor.AddComponent(&cmpD);
68 sensor.AddComponent(&cmpA);
69 sensor.SetArea(0., 0., -1., 5 * pitch, yDrift, 1.);
70
71 // Request signal calculation for the strip electrodes.
72 sensor.AddElectrode(&cmpA, "strip1");
73 sensor.AddElectrode(&cmpA, "strip2");
74 sensor.AddElectrode(&cmpA, "strip3");
75
76 // Set the time window [ns] for the signal calculation.
77 const double tMin = 0.;
78 const double tMax = 100.;
79 const double tStep = 0.05;
80 const int nTimeBins = int((tMax - tMin) / tStep);
81 sensor.SetTimeWindow(0., tStep, nTimeBins);
82
83 // We use microscopic tracking for simulating the electron avalanche.
84 AvalancheMicroscopic aval(&sensor);
85
86 // Simulate an ionizing particle (negative pion) using Heed.
87 TrackHeed track(&sensor);
88 track.SetParticle("pi-");
89 constexpr double momentum = 300.e6; // [eV / c]
90 track.SetMomentum(momentum);
91 track.EnableMagneticField();
92 // track.EnableElectricField();
93
94 // Construct a viewer to visualise the drift lines.
95 ViewDrift driftView;
96 track.EnablePlotting(&driftView);
97 aval.EnablePlotting(&driftView);
98 aval.EnableExcitationMarkers(false);
99 aval.EnableIonisationMarkers(false);
100
101 // Set the starting point of the incoming ionising track.
102 double xt = 0.05; // [cm]
103 double yt = yDrift;
104 double zt = 0.0;
105
106 // Now simulate a track.
107 track.NewTrack(xt, yt, zt, 0, 0, -1, 0);
108 // Loop over the clusters.
109 for (const auto& cluster : track.GetClusters()) {
110 for (const auto& electron : cluster.electrons) {
111 // Simulate the drift/avalanche of this electron.
112 aval.AvalancheElectron(electron.x, electron.y, electron.z,
113 electron.t, 0.1, 0., 0., 0.);
114 // Get the end point of the initial electron's trajectory.
115 const auto& p1 = aval.GetElectrons().front().path.back();
116 // Skip electrons that didn't hit the mesh plane.
117 if (fabs(p1.y - yMesh) > 1.e-6) continue;
118 // Move the electron into the amplification gap.
119 aval.AvalancheElectron(p1.x, yMesh - 1.e-6, p1.z, p1.t,
120 p1.energy, 0, -1., 0.);
121 }
122 }
123
124 // Calculate the accumulated charge on each strip.
125 sensor.IntegrateSignals();
126 const double q1 = sensor.GetSignal("strip1", nTimeBins - 1);
127 const double q2 = sensor.GetSignal("strip2", nTimeBins - 1);
128 const double q3 = sensor.GetSignal("strip3", nTimeBins - 1);
129
130 // Now calculate the reconstructed pion position in the Micromegas
131 // using the weighted average of the strip signals.
132 const double sum = q1 + q2 + q3;
133 double mean = (q1 * xStrip1 + q2 * xStrip2 + q3 * xStrip3) / sum;
134 const double res = fabs(xt - mean) * 10000.0;
135 std::cout << "---------------------------\n";
136 std::cout << "XMean: " << mean << " cm, XTrue: " << xt << " cm\n";
137 std::cout << "XTrue - XMean: " << res << " um\n";
138 std::cout << "---------------------------\n";
139
140 // Plotting
141 // This canvas will be used to display the drift lines and the field
142 gStyle->SetPadRightMargin(0.15);
143 TCanvas* c1 = new TCanvas("c1", "", 1400, 600);
144 c1->Divide(2, 1);
145
146 // Plot the drift lines.
147 driftView.SetArea(0.0, 0.0, 0.2, yDrift);
148 driftView.SetClusterMarkerSize(0.1);
149 driftView.SetCollisionMarkerSize(0.5);
150 driftView.SetCanvas((TPad*)c1->cd(1));
151 driftView.Plot(true);
152 // Plot the potential.
153 ViewField fieldView;
154 fieldView.SetSensor(&sensor);
155 fieldView.SetCanvas((TPad*)c1->cd(2));
156 fieldView.Plot("v", "cont1z");
157
158 c1->SaveAs("plot.pdf");
159 app.Run(true);
160 return 0;
161
162}
Calculate electron drift lines and avalanches using microscopic tracking.
const std::vector< Electron > & GetElectrons() const
void EnableIonisationMarkers(const bool on=true)
Draw a marker at every ionising collision or not.
void EnableExcitationMarkers(const bool on=true)
Draw a marker at every excitation or not.
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 EnablePlotting(ViewDrift *view, const size_t nColl=100)
Switch on drift line plotting.
void SetMedium(Medium *medium)
Set the medium inside the cell.
void AddPlaneY(const double y, const double voltage, const std::string &label="")
Add a plane at constant y.
void AddStripOnPlaneY(const char direction, const double y, const double smin, const double smax, const std::string &label, const double gap=-1.)
Add a strip in the x or z direction on an existing plane at constant y.
void SetMagneticField(const double bx, const double by, const double bz)
Set a constant magnetic field.
Definition Component.cc:115
void SetTimeWindow(const double tstart, const double tstep, const unsigned int nsteps)
Definition Sensor.cc:869
void AddElectrode(Component *comp, const std::string &label)
Add an electrode.
Definition Sensor.cc:396
void AddComponent(Component *comp)
Add a component.
Definition Sensor.cc:355
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
bool IntegrateSignals()
Replace the signals on all electrodes curve by their integrals.
Definition Sensor.cc:1331
bool SetArea(const bool verbose=false)
Set the user area to the default.
Definition Sensor.cc:187
Generate tracks using Heed++.
Definition TrackHeed.hh:35
void EnableMagneticField()
Take the magnetic field into account in the stepping algorithm.
Definition TrackHeed.cc:724
bool NewTrack(const double x0, const double y0, const double z0, const double t0, const double dx0, const double dy0, const double dz0) override
Definition TrackHeed.cc:87
const std::vector< Cluster > & GetClusters() const
Definition TrackHeed.hh:80
void EnablePlotting(ViewDrift *viewer)
Switch on plotting.
Definition Track.cc:178
void SetMomentum(const double p)
Set the particle momentum.
Definition Track.cc:143
virtual void SetParticle(const std::string &part)
Definition Track.cc:18
void SetCanvas(TPad *pad)
Set the canvas to be painted on.
Definition ViewBase.hh:28
void SetArea(const double xmin, const double ymin, const double xmax, const double ymax)
Definition ViewBase.cc:109
Visualize drift lines and tracks.
Definition ViewDrift.hh:19
void Plot(const bool twod=false, const bool axis=true, const bool snapshot=false)
Draw the drift lines.
Definition ViewDrift.cc:162
void SetClusterMarkerSize(const double size)
Set the size of the cluster markers (see TAttMarker).
Definition ViewDrift.cc:38
void SetCollisionMarkerSize(const double size)
Set the size of the collision markers (see TAttMarker).
Definition ViewDrift.cc:46
Visualize the potential or electric field of a component or sensor.
Definition ViewField.hh:15
void Plot(const std::string &option="v", const std::string &drawopt="arr")
Definition ViewField.cc:133
void SetSensor(Sensor *s)
Set the sensor for which to plot the field.
Definition ViewField.cc:73
int main(int argc, char *argv[])
Definition example.cpp:19
PlottingEngine plottingEngine