REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDetectorElectronDiffusionProcess.cxx
1
15
16#include "TRestDetectorElectronDiffusionProcess.h"
17
18using namespace std;
19
21
22TRestDetectorElectronDiffusionProcess::TRestDetectorElectronDiffusionProcess() { Initialize(); }
23
24TRestDetectorElectronDiffusionProcess::TRestDetectorElectronDiffusionProcess(const char* configFilename) {
25 Initialize();
26 if (LoadConfigFromFile(configFilename)) {
27 LoadDefaultConfig();
28 }
29}
30
31TRestDetectorElectronDiffusionProcess::~TRestDetectorElectronDiffusionProcess() { delete fOutputHitsEvent; }
32
33void TRestDetectorElectronDiffusionProcess::LoadDefaultConfig() {
34 SetTitle("Default config");
35
36 fElectricField = 2000;
37 fAttachment = 0;
38 fGasPressure = 1;
39}
40
42 SetSectionName(this->ClassName());
43 SetLibraryVersion(LIBRARY_VERSION);
44
45 fElectricField = 0;
46 fAttachment = 0;
47 fGasPressure = 1;
48
49 fTransDiffCoeff = 0;
50 fLonglDiffCoeff = 0;
51 fWvalue = 0;
52
53 fOutputHitsEvent = new TRestDetectorHitsEvent();
54 fInputHitsEvent = nullptr;
55
56 fGas = nullptr;
57 fReadout = nullptr;
58
59 fRandom = nullptr;
60}
61
62void TRestDetectorElectronDiffusionProcess::LoadConfig(const string& configFilename, const string& name) {
63 if (LoadConfigFromFile(configFilename, name)) LoadDefaultConfig();
64}
65
67 fRandom = new TRandom3(fSeed);
68
69 fGas = GetMetadata<TRestDetectorGas>();
70 if (fGas == nullptr) {
71 if (fLonglDiffCoeff == -1 || fTransDiffCoeff == -1) {
72 RESTWarning << "Gas has not been initialized" << RESTendl;
73 RESTError
74 << "TRestDetectorElectronDiffusionProcess: diffusion parameters are not defined in the rml "
75 "file!"
76 << RESTendl;
77 exit(-1);
78 }
79 if (fWvalue == -1) {
80 RESTWarning << "Gas has not been initialized" << RESTendl;
81 RESTError
82 << "TRestDetectorElectronDiffusionProcess: gas work function has not been defined in the "
83 "rml file!"
84 << RESTendl;
85 exit(-1);
86 }
87 } else {
88#ifndef USE_Garfield
89 RESTError << "A TRestDetectorGas definition was found but REST was not linked to Garfield libraries."
90 << RESTendl;
91 RESTError
92 << "Please, remove the TRestDetectorGas definition, and add gas parameters inside the process "
93 "TRestDetectorElectronDiffusionProcess"
94 << RESTendl;
95 exit(1);
96#endif
97 if (fGasPressure <= 0) fGasPressure = fGas->GetPressure();
98 if (fElectricField <= 0) fElectricField = fGas->GetElectricField();
99 if (fWvalue <= 0) fWvalue = fGas->GetWvalue();
100
101 fGas->SetPressure(fGasPressure);
102 fGas->SetElectricField(fElectricField);
103 fGas->SetW(fWvalue);
104
105 if (fLonglDiffCoeff <= 0) fLonglDiffCoeff = fGas->GetLongitudinalDiffusion(); // (cm)^1/2
106
107 if (fTransDiffCoeff <= 0) fTransDiffCoeff = fGas->GetTransversalDiffusion(); // (cm)^1/2
108 }
109
110 fReadout = GetMetadata<TRestDetectorReadout>();
111 if (fReadout == nullptr) {
112 cout << "REST ERROR: Readout has not been initialized" << endl;
113 exit(-1);
114 }
115}
116
118 fInputHitsEvent = (TRestDetectorHitsEvent*)inputEvent;
119 fOutputHitsEvent->SetEventInfo(fInputHitsEvent);
120
121 Int_t nHits = fInputHitsEvent->GetNumberOfHits();
122 if (nHits <= 0) return nullptr;
123
124 Int_t isAttached;
125
126 Int_t totalElectrons = fInputHitsEvent->GetEnergy() * REST_Units::eV / fWvalue;
127
128 Double_t wValue = fWvalue;
129 if (fMaxHits > 0 && totalElectrons > fMaxHits) {
130 // set a fake w-value if max hits are limited. this fake w-value will be larger
131 wValue = fInputHitsEvent->GetEnergy() * REST_Units::eV / fMaxHits;
132 }
133
134 for (int n = 0; n < nHits; n++) {
135 TRestHits* hits = fInputHitsEvent->GetHits();
136
137 Double_t eDep = hits->GetEnergy(n);
138
139 if (eDep > 0) {
140 const Double_t x = hits->GetX(n);
141 const Double_t y = hits->GetY(n);
142 const Double_t z = hits->GetZ(n);
143
144 for (int p = 0; p < fReadout->GetNumberOfReadoutPlanes(); p++) {
145 TRestDetectorReadoutPlane* plane = &(*fReadout)[p];
146
147 if (plane->isZInsideDriftVolume(z)) {
148 Double_t xDiff, yDiff, zDiff;
149
150 Double_t driftDistance = plane->GetDistanceTo({x, y, z});
151
152 Int_t numberOfElectrons;
153 if (fPoissonElectronExcitation) {
154 numberOfElectrons = fRandom->Poisson(eDep * REST_Units::eV / fWvalue);
155 if (wValue != fWvalue) {
156 // reduce the number of electrons to improve speed
157 numberOfElectrons = round(numberOfElectrons * fWvalue / wValue);
158 }
159 if (numberOfElectrons == 0 && eDep > 0) numberOfElectrons = 1;
160 } else {
161 numberOfElectrons = (Int_t)(eDep * REST_Units::eV / wValue);
162 if (numberOfElectrons == 0 && eDep > 0) numberOfElectrons = 1;
163 }
164
165 Double_t localWValue = eDep * REST_Units::eV / numberOfElectrons;
166
167 while (numberOfElectrons > 0) {
168 numberOfElectrons--;
169
170 Double_t longHitDiffusion =
171 10. * TMath::Sqrt(driftDistance / 10.) * fLonglDiffCoeff; // mm
172
173 Double_t transHitDiffusion =
174 10. * TMath::Sqrt(driftDistance / 10.) * fTransDiffCoeff; // mm
175
176 if (fAttachment)
177 isAttached = (fRandom->Uniform(0, 1) > pow(1 - fAttachment, driftDistance / 10.));
178 else
179 isAttached = 0;
180
181 if (isAttached == 0) {
182 xDiff = x + fRandom->Gaus(0, transHitDiffusion);
183
184 yDiff = y + fRandom->Gaus(0, transHitDiffusion);
185
186 zDiff = z + fRandom->Gaus(0, longHitDiffusion);
187
188 if (fUnitElectronEnergy) {
190 cout << "Adding hit. x : " << xDiff << " y : " << yDiff
191 << " z : " << zDiff << " (unit energy)" << endl;
192 fOutputHitsEvent->AddHit(xDiff, yDiff, zDiff, 1, hits->GetTime(n),
193 hits->GetType(n));
194 } else {
196 cout << "Adding hit. x : " << xDiff << " y : " << yDiff
197 << " z : " << zDiff
198 << " en : " << localWValue * REST_Units::keV / REST_Units::eV
199 << " keV" << endl;
200 fOutputHitsEvent->AddHit(xDiff, yDiff, zDiff,
201 localWValue * REST_Units::keV / REST_Units::eV,
202 hits->GetTime(n), hits->GetType(n));
203 }
204 }
205 }
206 }
207 }
208 }
209 }
210
212 cout << "TRestDetectorElectronDiffusionProcess. Input hits energy : " << fInputHitsEvent->GetEnergy()
213 << endl;
214 cout << "TRestDetectorElectronDiffusionProcess. Hits added : " << fOutputHitsEvent->GetNumberOfHits()
215 << endl;
216 cout << "TRestDetectorElectronDiffusionProcess. Hits total energy : " << fOutputHitsEvent->GetEnergy()
217 << endl;
219 }
220
221 return fOutputHitsEvent;
222}
223
225 // Function to be executed once at the end of the process
226 // (after all events have been processed)
227
228 // Start by calling the EndProcess function of the abstract class.
229 // Comment this if you don't want it.
230 // TRestEventProcess::EndProcess();
231}
232
234 fGasPressure = GetDblParameterWithUnits("gasPressure", -1.);
235 fElectricField = GetDblParameterWithUnits("electricField", -1.);
236 fWvalue = GetDblParameterWithUnits("Wvalue", (double)0) * REST_Units::eV;
237 fAttachment = StringToDouble(GetParameter("attachment", "0"));
238 fLonglDiffCoeff = StringToDouble(GetParameter("longitudinalDiffusionCoefficient", "-1"));
239 if (fLonglDiffCoeff == -1)
240 fLonglDiffCoeff = StringToDouble(GetParameter("longDiff", "-1"));
241 else {
242 RESTWarning << "longitudinalDiffusionCoeffient is now OBSOLETE! It will soon dissapear." << RESTendl;
243 RESTWarning << " Please use the shorter form of this parameter : longDiff" << RESTendl;
244 }
245
246 fTransDiffCoeff = StringToDouble(GetParameter("transversalDiffusionCoefficient", "-1"));
247 if (fTransDiffCoeff == -1)
248 fTransDiffCoeff = StringToDouble(GetParameter("transDiff", "-1"));
249 else {
250 RESTWarning << "transversalDiffusionCoeffient is now OBSOLETE! It will soon dissapear." << RESTendl;
251 RESTWarning << " Please use the shorter form of this parameter : transDiff" << RESTendl;
252 }
253 fMaxHits = StringToInteger(GetParameter("maxHits", "1000"));
254 fSeed = StringToDouble(GetParameter("seed", "0"));
255 fPoissonElectronExcitation = StringToBool(GetParameter("poissonElectronExcitation", "false"));
256 fUnitElectronEnergy = StringToBool(GetParameter("unitElectronEnergy", "false"));
257}
virtual void SetW(double value)
Sets the electric field of the drift volume. Given in V/mm.
virtual void SetElectricField(double value)
Sets the electric field. Must be given in V/mm.
virtual Double_t GetElectricField() const
Returns the electric field in V/mm.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
void EndProcess() override
To be executed at the end of the run (outside event loop)
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void Initialize() override
Making default settings.
void SetPressure(Double_t pressure) override
Defines the pressure of the gas.
Double_t GetLongitudinalDiffusion(Double_t E)
It returns the longitudinal diffusion in (cm)^1/2 for a given electric field in V/cm.
Double_t GetTransversalDiffusion(Double_t E)
It returns the transversal diffusion in (cm)^1/2 for a given electric field in V/cm.
void AddHit(Double_t x, Double_t y, Double_t z, Double_t en, Double_t t=0, REST_HitType type=XYZ)
Adds a new hit to this event.
Int_t isZInsideDriftVolume(Double_t z)
This method determines if a given position in z is inside the drift volume drifting distance for this...
Double_t GetDistanceTo(const TVector3 &pos) const
Returns the perpendicular distance to the readout plane from a given position pos.
Int_t GetNumberOfReadoutPlanes()
Returns the number of readout planes defined on the readout.
A base class for any REST event.
Definition: TRestEvent.h:38
void SetEventInfo(TRestEvent *eve)
Definition: TRestEvent.cxx:135
It saves a 3-coordinate position and an energy for each punctual deposition.
Definition: TRestHits.h:39
endl_t RESTendl
Termination flag object for TRestStringOutput.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
@ REST_Debug
+show the defined debug messages
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.
Int_t StringToInteger(std::string in)
Gets an integer from a string.