16#include "TRestDetectorElectronDiffusionProcess.h"
22TRestDetectorElectronDiffusionProcess::TRestDetectorElectronDiffusionProcess() {
Initialize(); }
24TRestDetectorElectronDiffusionProcess::TRestDetectorElectronDiffusionProcess(
const char* configFilename) {
31TRestDetectorElectronDiffusionProcess::~TRestDetectorElectronDiffusionProcess() {
delete fOutputHitsEvent; }
33void TRestDetectorElectronDiffusionProcess::LoadDefaultConfig() {
34 SetTitle(
"Default config");
36 fElectricField = 2000;
54 fInputHitsEvent =
nullptr;
62void TRestDetectorElectronDiffusionProcess::LoadConfig(
const string& configFilename,
const string& name) {
67 fRandom =
new TRandom3(fSeed);
69 fGas = GetMetadata<TRestDetectorGas>();
70 if (fGas ==
nullptr) {
71 if (fLonglDiffCoeff == -1 || fTransDiffCoeff == -1) {
72 RESTWarning <<
"Gas has not been initialized" <<
RESTendl;
74 <<
"TRestDetectorElectronDiffusionProcess: diffusion parameters are not defined in the rml "
80 RESTWarning <<
"Gas has not been initialized" <<
RESTendl;
82 <<
"TRestDetectorElectronDiffusionProcess: gas work function has not been defined in the "
89 RESTError <<
"A TRestDetectorGas definition was found but REST was not linked to Garfield libraries."
92 <<
"Please, remove the TRestDetectorGas definition, and add gas parameters inside the process "
93 "TRestDetectorElectronDiffusionProcess"
97 if (fGasPressure <= 0) fGasPressure = fGas->GetPressure();
99 if (fWvalue <= 0) fWvalue = fGas->GetWvalue();
110 fReadout = GetMetadata<TRestDetectorReadout>();
111 if (fReadout ==
nullptr) {
112 cout <<
"REST ERROR: Readout has not been initialized" << endl;
121 Int_t nHits = fInputHitsEvent->GetNumberOfHits();
122 if (nHits <= 0)
return nullptr;
126 Int_t totalElectrons = fInputHitsEvent->GetEnergy() * REST_Units::eV / fWvalue;
128 Double_t wValue = fWvalue;
129 if (fMaxHits > 0 && totalElectrons > fMaxHits) {
131 wValue = fInputHitsEvent->GetEnergy() * REST_Units::eV / fMaxHits;
134 for (
int n = 0; n < nHits; n++) {
135 TRestHits* hits = fInputHitsEvent->GetHits();
137 Double_t eDep = hits->GetEnergy(n);
140 const Double_t x = hits->GetX(n);
141 const Double_t y = hits->GetY(n);
142 const Double_t z = hits->GetZ(n);
148 Double_t xDiff, yDiff, zDiff;
152 Int_t numberOfElectrons;
153 if (fPoissonElectronExcitation) {
154 numberOfElectrons = fRandom->Poisson(eDep * REST_Units::eV / fWvalue);
155 if (wValue != fWvalue) {
157 numberOfElectrons = round(numberOfElectrons * fWvalue / wValue);
159 if (numberOfElectrons == 0 && eDep > 0) numberOfElectrons = 1;
161 numberOfElectrons = (Int_t)(eDep * REST_Units::eV / wValue);
162 if (numberOfElectrons == 0 && eDep > 0) numberOfElectrons = 1;
165 Double_t localWValue = eDep * REST_Units::eV / numberOfElectrons;
167 while (numberOfElectrons > 0) {
170 Double_t longHitDiffusion =
171 10. * TMath::Sqrt(driftDistance / 10.) * fLonglDiffCoeff;
173 Double_t transHitDiffusion =
174 10. * TMath::Sqrt(driftDistance / 10.) * fTransDiffCoeff;
177 isAttached = (fRandom->Uniform(0, 1) > pow(1 - fAttachment, driftDistance / 10.));
181 if (isAttached == 0) {
182 xDiff = x + fRandom->Gaus(0, transHitDiffusion);
184 yDiff = y + fRandom->Gaus(0, transHitDiffusion);
186 zDiff = z + fRandom->Gaus(0, longHitDiffusion);
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),
196 cout <<
"Adding hit. x : " << xDiff <<
" y : " << yDiff
198 <<
" en : " << localWValue * REST_Units::keV / REST_Units::eV
200 fOutputHitsEvent->
AddHit(xDiff, yDiff, zDiff,
201 localWValue * REST_Units::keV / REST_Units::eV,
202 hits->GetTime(n), hits->GetType(n));
212 cout <<
"TRestDetectorElectronDiffusionProcess. Input hits energy : " << fInputHitsEvent->GetEnergy()
214 cout <<
"TRestDetectorElectronDiffusionProcess. Hits added : " << fOutputHitsEvent->GetNumberOfHits()
216 cout <<
"TRestDetectorElectronDiffusionProcess. Hits total energy : " << fOutputHitsEvent->GetEnergy()
221 return fOutputHitsEvent;
234 fGasPressure = GetDblParameterWithUnits(
"gasPressure", -1.);
235 fElectricField = GetDblParameterWithUnits(
"electricField", -1.);
236 fWvalue = GetDblParameterWithUnits(
"Wvalue", (
double)0) * REST_Units::eV;
239 if (fLonglDiffCoeff == -1)
242 RESTWarning <<
"longitudinalDiffusionCoeffient is now OBSOLETE! It will soon dissapear." <<
RESTendl;
243 RESTWarning <<
" Please use the shorter form of this parameter : longDiff" <<
RESTendl;
247 if (fTransDiffCoeff == -1)
250 RESTWarning <<
"transversalDiffusionCoeffient is now OBSOLETE! It will soon dissapear." <<
RESTendl;
251 RESTWarning <<
" Please use the shorter form of this parameter : transDiff" <<
RESTendl;
255 fPoissonElectronExcitation = StringToBool(
GetParameter(
"poissonElectronExcitation",
"false"));
256 fUnitElectronEnergy = StringToBool(
GetParameter(
"unitElectronEnergy",
"false"));
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.
void SetEventInfo(TRestEvent *eve)
It saves a 3-coordinate position and an energy for each punctual deposition.
@ REST_Extreme
show everything
@ 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.