FDsimG4Materials.cc
Go to the documentation of this file.
1 #include "FDsimG4Materials.hh"
3 #include "G4Material.hh"
4 #include "G4MaterialTable.hh"
5 #include "G4Element.hh"
6 #include "G4ElementTable.hh"
7 #include "G4UserLimits.hh"
8 #include "G4RunManager.hh"
9 
10 #include "geomdefs.hh"
11 #include <unconfig.h>
12 #include <utl/AugerUnits.h>
13 #include <utl/Point.h>
14 #include <utl/ReferenceEllipsoid.h>
15 #include <det/Detector.h>
16 #include <fdet/FDetector.h>
17 #include <fdet/Eye.h>
18 #include <fdet/Telescope.h>
19 #include <fdet/Corrector.h>
20 #include <fdet/Filter.h>
21 #include <atm/Atmosphere.h>
22 #include <atm/ProfileResult.h>
23 
24 using namespace TelescopeSimulatorLX ;
25 using namespace std;
26 
28 
30 {
31  if(fMaterials)
32  { G4Exception("FDsimG4Materials constructed twice."); }
33 
34  fMaterials = this;
35  fTelescope = &tel;
36  ConstructTableOfMaterials() ;
37 }
38 
39 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
40 
42 
43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
44 
46 {
47  const G4RunManager* runManager = G4RunManager::GetRunManager();
48  const FDsimG4DetectorConstruction* DetectorConstruction =
49  dynamic_cast<const FDsimG4DetectorConstruction*>(runManager->GetUserDetectorConstruction());
50  G4int VerbosityLevel = DetectorConstruction->fVerbosityLevel;
51 
52  det::Detector& detector = det::Detector::GetInstance();
53  const fdet::FDetector& detFD = detector.GetFDetector();
54  const unsigned int eyeId = fTelescope->GetEyeId();
55  const fdet::Eye& eye = detFD.GetEye(eyeId);
56  const fdet::Corrector& corrector = fTelescope->GetCorrector();
57  const fdet::Filter& filter = fTelescope->GetFilter();
58 
59  const utl::Point& eyePos = eye.GetPosition();
60  const utl::ReferenceEllipsoid& wgs84 =
62 
63  const double minWl = detFD.GetModelMinWavelength();
64  const double maxWl = detFD.GetModelMaxWavelength();
65 
66  double wvl;
67  G4double energy;
68  G4double rindex;
69  G4double transmittance;
70  G4double abslength;
71 
72  G4double a;
73  G4double z;
74  G4double density;
75  G4String name;
76  G4String symbol;
77  G4int nel;
78 
79  // ------------- Elements -------------
80  a = 1.01*g/mole;
81  G4Element* elH = new G4Element(name="Hydrogen", symbol="H", z=1., a);
82 
83  a = 12.01*g/mole;
84  G4Element* elC = new G4Element(name="Carbon", symbol="C", z=6., a);
85 
86  a = 14.01*g/mole;
87  G4Element* elN = new G4Element(name="Nitrogen", symbol="N", z=7., a);
88 
89  a = 16.00*g/mole;
90  G4Element* elO = new G4Element(name="Oxygen", symbol="O", z=8., a);
91 
92  // ------------- Materials -------------
93  // Air
94  density = 1.29e-03*g/cm3;
95  G4Material* Air = new G4Material(name="Air", density, nel=2);
96  Air->AddElement(elN, .7);
97  Air->AddElement(elO, .3);
98 
99 
100  // Atmosphere
101  {
102  const atm::Atmosphere& atmosphere = detector.GetAtmosphere();
103  double eyeAltitude = wgs84.PointToLatitudeLongitudeHeight (eyePos).get<2> ();
104 
105  const atm::ProfileResult& temperatureVsHeight =
106  atmosphere.EvaluateTemperatureVsHeight();
107  const atm::ProfileResult& pressureVsHeight =
108  atmosphere.EvaluatePressureVsHeight();
109  const atm::ProfileResult& densityVsHeight =
110  atmosphere.EvaluateDensityVsHeight();
111 
112  G4double pressure =
113  pressureVsHeight.Y(eyeAltitude)/utl::atmosphere * CLHEP::atmosphere;
114  G4double temperature =
115  temperatureVsHeight.Y(eyeAltitude)/utl::kelvin * CLHEP::kelvin;
116  G4double density =
117  densityVsHeight.Y(eyeAltitude)/(utl::g/utl::cm3) * (CLHEP::g/CLHEP::cm3);
118 
119 
120  G4State state = kStateGas;
121  const G4int nElements = 2;
122  G4Material* Atmosphere =
123  new G4Material("Atmosphere", density,nElements,state,temperature, pressure);
124  Atmosphere->AddElement(elN,0.7);
125  Atmosphere->AddElement(elO,0.3);
126 
127  // air refractive index
128 
129  G4MaterialPropertiesTable* atmosphereMPT = new G4MaterialPropertiesTable();
130  atmosphereMPT->AddProperty("RINDEX", new G4MaterialPropertyVector()) ;
131 
132  const unsigned int NSTEPS = 10;
133  double deltaWl = (maxWl - minWl)/float(NSTEPS-1);
134 
135  for(unsigned int j=0 ; j<NSTEPS ; ++j){
136  wvl = minWl + j * deltaWl;
137  const atm::ProfileResult& refractionIndexVsHeight =
138  atmosphere.EvaluateRefractionIndexVsHeight(wvl);
139  rindex = refractionIndexVsHeight.Y(eyeAltitude);
140  energy = (CLHEP::h_Planck*CLHEP::c_light)/(wvl/utl::nanometer * CLHEP::nm);
141  atmosphereMPT->AddEntry("RINDEX", energy, rindex);
142  }
143  Atmosphere->SetMaterialPropertiesTable(atmosphereMPT);
144 
145  if (VerbosityLevel > 0) {
146  G4cerr << "Material Properties Table for atmosphere: " << G4endl ;
147  atmosphereMPT->DumpTable();
148  }
149  }
150 
151  // Aluminum
152  // ---------
153  a = 26.98*g/mole;
154  density = 2.7*g/cm3;
155  new G4Material(name="Aluminum", z=13., a, density);
156 
157 
158  // Plastic ;
159  // -------------
160 
161  density = 1.032*g/cm3;
162  G4Material *Plastic = new G4Material(name="MirrorPlastic",density, nel=2);
163  Plastic->AddElement(elC,9) ;
164  Plastic->AddElement(elH,10) ;
165 
166  {
167  const G4int NENTRIES = 2 ;
168  G4double LAMBDA[NENTRIES] = {0.0*eV,10.0*eV};
169  G4double REFLECTIVITY[NENTRIES] = {0.91,0.91};
170 
171  G4MaterialPropertiesTable* MPT = new G4MaterialPropertiesTable();
172  MPT->AddProperty("REFLECTIVITY", LAMBDA, REFLECTIVITY, NENTRIES);
173  Plastic->SetMaterialPropertiesTable(MPT);
174  }
175 
176 
178  // BK7
179  // -------------
180 
181  // The chemical composition is that of Acrylic. It is not relevant for the optical processes.
182 
183  density = 1.19*g/cm3;
184  G4Material* BK7 = new G4Material(name="BK7", density, nel=3);
185  BK7->AddElement(elC, 5);
186  BK7->AddElement(elH, 8);
187  BK7->AddElement(elO, 2);
188 
189  G4MaterialPropertiesTable *MPT_BK7 = new G4MaterialPropertiesTable();
190  MPT_BK7->AddProperty("RINDEX", new G4MaterialPropertyVector()) ;
191  MPT_BK7->AddProperty("ABSLENGTH", new G4MaterialPropertyVector()) ;
192 
193  const utl::TabulatedFunction& refractiveIndexBK7 = corrector.GetRefractiveIndex();
194  const utl::TabulatedFunction& transmittanceBK7 = corrector.GetTransmittance();
195 
196  unsigned int nPoints;
197 
198  nPoints = refractiveIndexBK7.GetNPoints();
199  for(unsigned int j=0 ; j<nPoints ; ++j){
200  wvl = refractiveIndexBK7.GetX(j);
201  rindex = refractiveIndexBK7.GetY(j);
202  energy = (CLHEP::h_Planck*CLHEP::c_light)/(wvl/utl::nanometer * CLHEP::nm);
203 
204  MPT_BK7->AddEntry("RINDEX",energy,rindex);
205  }
206 
207  nPoints = transmittanceBK7.GetNPoints();
208  for(unsigned int j=0 ; j<nPoints ; ++j){
209  wvl = transmittanceBK7.GetX(j);
210  transmittance = transmittanceBK7.GetY(j); // Internal transmittance for 1cm thickness BK7 glass.
211  energy = (CLHEP::h_Planck*CLHEP::c_light)/(wvl/utl::nanometer * CLHEP::nm);
212 
213  if (transmittance <= DBL_MIN)
214  abslength = DBL_MIN;
215  else
216  abslength = -10.0*CLHEP::mm/log(transmittance) ;
217 
218  MPT_BK7->AddEntry("ABSLENGTH", energy, abslength);
219  }
220 
221  BK7->SetMaterialPropertiesTable(MPT_BK7);
222 
223  if (VerbosityLevel > 0) {
224  G4cerr << "Material properties table for lens (BK7):" << G4endl ;
225  MPT_BK7->DumpTable();
226  }
227 
229  // M-UG6 Filter glass from Schott-Desag
230  // ------------------
231 
232  // For now the chemical composition is that of Acrylic - not relevant for the optical processes anyway
233 
234  density = 1.19*g/cm3;
235  G4Material* MUG6 = new G4Material(name="M-UG6", density, nel=3);
236  MUG6->AddElement(elC, 5);
237  MUG6->AddElement(elH, 8);
238  MUG6->AddElement(elO, 2);
239 
240  G4MaterialPropertiesTable *MPT_MUG6 = new G4MaterialPropertiesTable();
241 
242  MPT_MUG6->AddProperty("RINDEX", new G4MaterialPropertyVector()) ;
243  MPT_MUG6->AddProperty("ABSLENGTH", new G4MaterialPropertyVector()) ;
244 
245  MPT_MUG6->AddEntry("RINDEX",0.1*eV, 1.526);
246  MPT_MUG6->AddEntry("RINDEX",10.0*eV, 1.526);
247 
248  // Transmittance for 3.25 mm thickness M-UG6 glass.
249  const utl::TabulatedFunction& transmittanceMUG6 = filter.GetTransmittance();
250 
251  nPoints = transmittanceMUG6.GetNPoints();
252  G4double intTransmittance ;
253  for(unsigned int j=0 ; j<nPoints ; ++j){
254  wvl = transmittanceMUG6.GetX(j);
255  transmittance = transmittanceMUG6.GetY(j);
256  energy = (CLHEP::h_Planck*CLHEP::c_light)/(wvl/utl::nanometer * CLHEP::nm);
257 
258  // Compute the internal transmittance (Ti) using the relation Ti = T/P, where T is the transmittance and P is the reflection factor: P = 2n/(n^2+1)
259 
260  rindex = MPT_MUG6->GetProperty("RINDEX")->GetProperty(energy) ;
261  G4double P = 2.0*rindex/(rindex*rindex + 1.0) ;
262 
263  if (P > 0.0)
264  intTransmittance = transmittance/P ;
265  else
266  intTransmittance = DBL_MIN;
267 
268  if (intTransmittance <= DBL_MIN)
269  abslength = DBL_MIN;
270  else if (intTransmittance >= 1.0)
271  abslength = DBL_MAX;
272  else
273  abslength = -3.25*CLHEP::mm/(std::log(intTransmittance)) ;
274 
275  MPT_MUG6->AddEntry("ABSLENGTH", energy, abslength);
276  }
277 
278  MUG6->SetMaterialPropertiesTable(MPT_MUG6);
279 
280  if (VerbosityLevel > 0) {
281  G4cerr << "Material properties table for filter (MUG6):" << G4endl ;
282  MPT_MUG6->DumpTable();
283  }
284 
286  // Lime glass window of XP3062 photomultipliers of the FD.
287  // ------------------
288 
289  // For now the chemical composition is that of Acrylic - not relevant for the optical processes anyway !!!
290 
291  density = 1.19*g/cm3;
292  G4Material* LimeGlass = new G4Material(name="LimeGlass", density, nel=3);
293  LimeGlass->AddElement(elC, 5);
294  LimeGlass->AddElement(elH, 8);
295  LimeGlass->AddElement(elO, 2);
296 
297  G4MaterialPropertiesTable *MPT_LimeGlass = new G4MaterialPropertiesTable();
298 
299  // Data from Schott B270
300 
301  MPT_LimeGlass->AddProperty("RINDEX", new G4MaterialPropertyVector()) ;
302  MPT_LimeGlass->AddProperty("ABSLENGTH", new G4MaterialPropertyVector()) ;
303 
304 
305  // n(lambda) for lambda=240,260,280 nm, were obtained by fitting the Cauchy dispersion law
306  // (n(lambda) = a + b/lambda^2) to the data for lambda>= 313nm.
307  {
308  const G4int nEntries = 10;
309  G4double lambda[nEntries] =
310  {240.0*nm,260.0*nm,280.0*nm,313.0*nm,334.0*nm,365.0*nm,405.0*nm,436.0*nm,546.0*nm,700.0*nm};
311  G4double Rindex[nEntries] =
312  {1.59,1.58,1.57,1.56,1.5525,1.545,1.54,1.535,1.525,1.52};
313 
314  G4double energy;
315  for (G4int i=0; i < nEntries; i++) {
316  energy = h_Planck*c_light/lambda[i] ;
317  MPT_LimeGlass->AddEntry("RINDEX", energy, Rindex[i]);
318  }
319  }
320 
321  {
322  const G4int nEntries = 17;
323  G4double lambda[nEntries] = {
324  240.0*nm,280*nm,300*nm,310*nm,320*nm,330*nm,340*nm,350*nm,360*nm,370*nm,380*nm,
325  390*nm,400*nm,450*nm,500*nm,600*nm,700*nm};
326 
327  G4double Transmittance[nEntries] =
328  {0.0,0.0,35.1,60.0,76.0,84.2,88.0,89.8,90.6,90.8,90.9,
329  89.2,90.0,90.3,91.2,91.3,91.1};
330 
331  G4double Thickness[nEntries] =
332  {1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm, 1.0*mm,
333  10.0*mm, 10.0*mm, 10.0*mm, 10.0*mm, 10.0*mm, 10.0*mm};
334 
335  G4double abslength ;
336  G4double energy ;
337  for (G4int i = 0; i < nEntries; i++) {
338  energy = h_Planck*c_light/lambda[i] ;
339  Transmittance[i] = Transmittance[i]/100.0;
340 
341  // Compute the internal transmittance (Ti) using the relation Ti =
342  // T/P, where T is the transmittance
343  // and P is the reflection factor: P = 2n/(n^2+1)
344 
345  G4double Rind = 0.0;
346  Rind = MPT_LimeGlass->GetProperty("RINDEX")->GetProperty(energy) ;
347  G4double P = 2.0*Rind/(Rind*Rind+1.0) ;
348 
349  G4double InternalTransmittance ;
350 
351  if (P > 0.0)
352  InternalTransmittance = Transmittance[i]/P;
353  else
354  InternalTransmittance = DBL_MIN;
355 
356  if (InternalTransmittance <= DBL_MIN)
357  abslength = DBL_MIN;
358  else if (InternalTransmittance >= 1.0)
359  abslength = DBL_MAX;
360  else
361  abslength = -Thickness[i]/(std::log(InternalTransmittance));
362 
363  MPT_LimeGlass->AddEntry("ABSLENGTH", energy, abslength);
364  }
365  }
366 
367  LimeGlass->SetMaterialPropertiesTable(MPT_LimeGlass);
368 
369  if (VerbosityLevel > 0) {
370  G4cerr << "Material properties table for PMT window (Lime Glass):" << G4endl ;
371  MPT_LimeGlass->DumpTable();
372  }
373 }
const double eV
Definition: GalacticUnits.h:35
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
constexpr double mm
Definition: AugerUnits.h:113
Point object.
Definition: Point.h:32
constexpr double atmosphere
Definition: AugerUnits.h:215
constexpr double cm3
Definition: AugerUnits.h:119
FDsimG4Materials(const fdet::Telescope &tel)
Class to hold collection (x,y) points and provide interpolation between them.
const atm::ProfileResult & EvaluatePressureVsHeight() const
Tabulated function giving Y=air pressure as a function of X=height.
const utl::TabulatedFunction & GetTransmittance() const
Average transmittance of the filter as a function of the wavelength.
const atm::ProfileResult & EvaluateDensityVsHeight() const
Tabulated function giving Y=density as a function of X=height.
const utl::TabulatedFunction & GetTransmittance() const
Transmittance as a function of the wavelength.
Definition: Corrector.cc:110
double GetModelMinWavelength() const
Definition: FDetector.cc:291
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
static const ReferenceEllipsoid & Get(const EllipsoidID theID)
Get known ellipsoid by registered ID.
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
constexpr double nanometer
Definition: AugerUnits.h:102
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
static FDsimG4Materials * fMaterials
constexpr double mole
Definition: AugerUnits.h:262
Reference ellipsoids for UTM transformations.
double GetModelMaxWavelength() const
Definition: FDetector.cc:312
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
const fdet::FDetector & GetFDetector() const
Definition: Detector.cc:131
constexpr double g
Definition: AugerUnits.h:200
Description of a corrector ring.
Definition: Corrector.h:36
const double & GetY(const unsigned int idx) const
constexpr double kelvin
Definition: AugerUnits.h:259
const utl::TabulatedFunction & GetRefractiveIndex() const
Index of refraction as a funcction of the wavelength.
Definition: Corrector.cc:118
Detector description interface for Telescope-related data.
const double & GetX(const unsigned int idx) const
Description of a filter.
const atm::ProfileResult & EvaluateRefractionIndexVsHeight() const
Tabulated function giving Y=refraction index as a function of X=height.
utl::Point GetPosition() const
Eye position.
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.

, generated on Tue Sep 26 2023.