REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDetectorGas.h
1 /*************************************************************************
2  * This file is part of the REST software framework. *
3  * *
4  * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5  * For more information see http://gifna.unizar.es/trex *
6  * *
7  * REST is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * REST is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have a copy of the GNU General Public License along with *
18  * REST in $REST_PATH/LICENSE. *
19  * If not, see http://www.gnu.org/licenses/. *
20  * For the list of contributors see $REST_PATH/CREDITS. *
21  *************************************************************************/
22 
23 #ifndef RestCore_TRestDetectorGas
24 #define RestCore_TRestDetectorGas
25 
26 #include <TApplication.h>
27 #include <TArrayI.h>
28 #include <TAxis.h>
29 #include <TCanvas.h>
30 #include <TGraph.h>
31 #include <TNamed.h>
32 #include <TROOT.h>
33 #include <TRestMetadata.h>
34 #include <TString.h>
35 #include <TSystem.h>
36 #include <TVector3.h>
37 
38 #include <cstdlib>
39 #include <fstream>
40 #include <iostream>
41 
42 #include "TRestDetectorDriftVolume.h"
43 
44 #if defined USE_Garfield
45 #include <ComponentConstant.hh>
46 #include <GeometrySimple.hh>
47 #include <MediumMagboltz.hh>
48 #include <Sensor.hh>
49 #include <SolidBox.hh>
50 #include <TrackHeed.hh>
51 using namespace Garfield;
52 #else
53 class MediumMagboltz;
54 #endif
55 
56 const int RESTGAS_ERROR = -1;
57 const int RESTGAS_INTITIALIZED = 0;
58 const int RESTGAS_CFG_LOADED = 1;
59 const int RESTGAS_GASFILE_LOADED = 2;
60 
64  private:
65  MediumMagboltz* fGasMedium;
67 
68  Int_t fStatus; // Used to define the status of the gas : RESTGAS_ERROR,
69  // RESTGAS_INTITIALIZED, RESTGAS_CFG_LOADED,
70  // RESTGAS_GASFILE_LOADED
71  TString fGasFilename; // The filename of the Magboltz gas file.
72  Int_t fNofGases; // Number of different elements composing the gas mixture
73 
74  Int_t fNCollisions; // Number of collisions used in the Magboltz calculation.
75  Double_t fMaxElectronEnergy; // Maximum electron energy, in eV, used in
76  // Magboltz gas calculation.
77 
78  std::vector<TString> fGasComponentName; // A std::string std::vector storing the names
79  // of each of the gas components
80  std::vector<Double_t> fGasComponentFraction; // A double std::vector storing the fraction values of
81  // each of the gas components
82 
83  Int_t fEnodes; // Number of electric field nodes used in the gas calculation.
84  Double_t fEmax; // Minimum value of the electric field used for the gas
85  // calculation.
86  Double_t fEmin; // Maximum value of the electric field used for the gas
87  // calculation.
88 
89  std::vector<Double_t> fEFields; // The electric field nodes as calculated by
90  // Garfield::MediumMagboltz.
91  std::vector<Double_t> fBFields; // The magnetic field nodes as calculated by
92  // Garfield::MediumMagboltz.
93  std::vector<Double_t> fAngles; // The field angles as calculated by Garfield::MediumMagboltz.
94 
95  TString fGDMLMaterialRef; // The corresponding material reference name in
96  // GDML description
97 
98  bool fGasGeneration;
101 
102  TString fGasOutputPath;
104 
105  TString fGasServer;
108 
109  TString fGasFileContent; // Used for saving the gasFile into a root file
110 
111  Bool_t fTest = false;
112 
113  void InitFromConfigFile() override;
114  std::string ConstructFilename();
115 
116  void AddGasComponent(std::string gasName, Double_t fraction);
117 
118  void GenerateGasFile();
119 
120  void UploadGasToServer(std::string gasFilename);
121 
122  Double_t GetDriftVelocity(Double_t E);
123  Double_t GetLongitudinalDiffusion(Double_t E);
124  Double_t GetTransversalDiffusion(Double_t E);
125  Double_t GetTownsendCoefficient(Double_t E);
126  Double_t GetAttachmentCoefficient(Double_t E);
127 
128  public:
130  TRestDetectorGas(const char* configFilename, std::string name = "", bool gasGeneration = false,
131  bool test = false);
132  ~TRestDetectorGas();
133 
136  inline void EnableGasGeneration() { fGasGeneration = true; }
137 
139  inline bool GasFileGenerationEnabled() const { return fGasGeneration; }
140 
142  inline bool GasFileLoaded() const { return fStatus == RESTGAS_GASFILE_LOADED; }
143 
144  void Initialize() override;
145 
146  void LoadGasFile();
147 
148  std::string FindGasFile(std::string name);
149 
150  void CalcGarField(double Emin, double Emax, int n);
151 
152  Int_t Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) override;
153 
154  void InitFromRootFile() override;
155 
158  inline Double_t GetMaxElectronEnergy() const { return fMaxElectronEnergy; }
159 
161  inline Int_t GetNofGases() const { return fNofGases; }
162 
164  inline TString GetGasComponentName(Int_t n) {
165  if (n >= GetNofGases()) {
166  std::cout << "REST WARNING. Gas name component n=" << n << " requested. But only "
167  << GetNofGases() << " component(s) in the mixture." << std::endl;
168  return "";
169  }
170  return fGasComponentName[n];
171  }
172 
173  TString GetGasMixture();
174 
175  Double_t GetDriftVelocity() override {
176  if (fElectricField == 0) {
177  RESTWarning << "TRestDetectorGas::GetDriftVelocity. Warning fElectricField is zero!" << RESTendl;
178  RESTWarning << " - Use: TRestDetectorGas::SetElectricField( field[V/mm] ) to set the field value"
179  << RESTendl;
180  }
181  return GetDriftVelocity(fElectricField * units("V/cm")) / units("cm/us");
182  } // in standard unit mm/us
183 
185  Double_t GetLongitudinalDiffusion() override {
186  if (fElectricField == 0) {
187  RESTWarning << "TRestDetectorGas::GetLongitudinalDiffusion. Warning fElectricField is zero!"
188  << RESTendl;
189  RESTWarning << " - Use: TRestDetectorGas::SetElectricField( field[V/mm] ) to set the field value"
190  << RESTendl;
191  }
192  return GetLongitudinalDiffusion(fElectricField * units("V/cm"));
193  }
194 
196  Double_t GetTransversalDiffusion() override {
197  if (fElectricField == 0) {
198  RESTWarning << "TRestDetectorGas::GetTransversalDiffusion. Warning fElectricField is zero!"
199  << RESTendl;
200  RESTWarning << " - Use: TRestDetectorGas::SetElectricField( field[V/mm] ) to set the field value"
201  << RESTendl;
202  }
203  return GetTransversalDiffusion(fElectricField * units("V/cm"));
204  }
205 
206  Double_t GetTownsendCoefficient() override {
207  if (fElectricField == 0) {
208  RESTWarning << "TRestDetectorGas::GetTownsendCoefficient. Warning fElectricField is zero!"
209  << RESTendl;
210  RESTWarning << " - Use: TRestDetectorGas::SetElectricField( field[V/mm] ) to set the field value"
211  << RESTendl;
212  }
213  return GetTownsendCoefficient(fElectricField * units("V/cm"));
214  }
215 
216  Double_t GetAttachmentCoefficient() override {
217  if (fElectricField == 0) {
218  RESTWarning << "TRestDetectorGas::GetAttachmentCoefficient. Warning fElectricField is zero!"
219  << RESTendl;
220  RESTWarning << " - Use: TRestDetectorGas::SetElectricField( field[V/mm] ) to set the field value"
221  << RESTendl;
222  }
223  return GetAttachmentCoefficient(fElectricField * units("V/cm"));
224  }
225 
226  void GetGasWorkFunction();
227 
229  inline Double_t GetGasComponentFraction(Int_t n) {
230  if (n >= GetNofGases()) {
231  std::cout << "REST WARNING. Gas fraction for component n=" << n << " requested. But only "
232  << GetNofGases() << " component(s) in the mixture." << std::endl;
233  return 0.;
234  }
235 
236  return fGasComponentFraction[n];
237  }
238 
240  inline MediumMagboltz* GetGasMedium() const { return fGasMedium; };
241 
243  inline TString GetGDMLMaterialRef() const { return fGDMLMaterialRef; };
244 
245  void SetPressure(Double_t pressure) override;
246  void SetTemperature(Double_t temperature) override;
247 
249  inline void SetMaxElectronEnergy(Double_t energy) { fMaxElectronEnergy = energy; }
250 
251  void PlotDriftVelocity(Double_t eMin, Double_t eMax, Int_t nSteps);
252  void PlotLongitudinalDiffusion(Double_t eMin, Double_t eMax, Int_t nSteps);
253  void PlotTransversalDiffusion(Double_t eMin, Double_t eMax, Int_t nSteps);
254  void PlotTownsendCoefficient(Double_t eMin, Double_t eMax, Int_t nSteps);
255  void PrintGasInfo();
256  inline void PrintGasFileContent() { std::cout << fGasFileContent << std::endl; };
257 
259  void PrintMetadata() override { PrintGasInfo(); }
260 
261  ClassDefOverride(TRestDetectorGas, 3); // Gas Parameters
262 };
263 
264 #endif
bool GasFileGenerationEnabled() const
Returns true if the file generation is enabled. False otherwise.
void PrintMetadata() override
Prints the metadata information from the gas.
TString GetGasComponentName(Int_t n)
Returns the gas component n.
Int_t GetNofGases() const
Returns the number of gas elements/compounds present in the gas mixture.
bool GasFileLoaded() const
Returns true if the gas file has been properly loaded. False otherwise.
Double_t GetTransversalDiffusion() override
Returns the transversal diffusion in (cm)^1/2.
Double_t GetMaxElectronEnergy() const
Double_t GetDriftVelocity() override
Returns the drift velocity in mm/us.
MediumMagboltz * GetGasMedium() const
Return pointer to Garfield::MediumGas for gas properties.
TString GetGDMLMaterialRef() const
Return reference name of the corresponding material in GDML file.
Double_t GetGasComponentFraction(Int_t n)
Returns the gas fraction in volume for component n.
void SetMaxElectronEnergy(Double_t energy)
Sets the maximum electron energy to be used in gas generation.
Double_t GetLongitudinalDiffusion() override
Returns the longitudinal diffusion in (cm)^1/2.