source: trunk/Mars/msim/MAtmosphere.h@ 19894

Last change on this file since 19894 was 19852, checked in by tbretz, 5 years ago
Changed the default atmosphere without user initailization to Keilhauer US Std. Make sure that the overburden below the obs level is 0. Split the Init functions such that the observation level can be changed indendently from the atmospshere. Copy the height levels from MRunHeader.
File size: 5.3 KB
Line 
1#ifndef MARS_MAtmosphere
2#define MARS_MAtmosphere
3
4#include <TROOT.h>
5
6class TGraph;
7class MPhotonData;
8class MCorsikaRunHeader;
9
10class MAtmRayleigh
11{
12private:
13 static const Double_t fgMeanFreePath; // [g/cm^2] Mean free path for scattering Rayleigh XR
14 static const Double_t fgEarthRadiush; // [cm] Default Earth Radius
15
16 Double_t fR; // [cm] Earth radius to be used
17
18 Float_t fHeight[5]; // Layer boundaries (atmospheric layer)
19
20 // Parameters of the different atmospheres. We use the same parametrization
21 // shape as in Corsika atmospheric models (see Corsika manual, appendix D).
22 // The values here can be/are obtained from the Corsika output
23 // fAtmA is not required as it is an offset which cancels out
24 //Float_t fAtmA[4]; // The index refers to the atmospheric layer (starting from sea level and going upwards)
25 Float_t fAtmB[4]; // The index refers to the atmospheric layer (starting from sea level and going upwards)
26 Float_t fAtmC[4]; // The index refers to the atmospheric layer (starting from sea level and going upwards)
27
28 Double_t fRho[5]; // Precalculated integrals for rayleigh scatterning
29
30 void PreCalcRho();
31
32protected:
33 Float_t fObsLevel; // [cm] observation level a.s.l.
34
35public:
36 // Default constructor
37 MAtmRayleigh();
38
39 // Init an atmosphere from the data stored in MCorsikaRunHeader
40 MAtmRayleigh(const MCorsikaRunHeader &h)
41 {
42 Init(h);
43 }
44
45 // Check if the ovservation level has been correctly initialized
46 // Used as a marker for correct initialization
47 Bool_t IsValid() const { return fObsLevel>=0; }
48
49 // Get the Earth radius to be used
50 Double_t R() const { return fR; }
51
52 void Init(Float_t obs);
53 void Init(Float_t obs, const Float_t *atmb, const Float_t *atmc, const Float_t *height);
54 void Init(const MCorsikaRunHeader &h);
55
56 Double_t GetVerticalThickness(Double_t height) const;
57 Double_t CalcTransmission(Double_t height, Double_t wavelength, Double_t sin2) const;
58
59 static Double_t Fcn(const Double_t *xx, const Double_t *par)
60 {
61 const Double_t *A = par;
62 const Double_t *B = par+5;
63 const Double_t *C = par+10;
64
65 double H[6] = { 0, 0, 0, 0, 0, 1e100 };
66
67 const Double_t x = xx[0]*1e5; // km -> cm
68
69 for (int i=0; i<4; i++)
70 {
71 H[i+1] = log(C[i+1]/C[i] * B[i]/B[i+1]) / (1./C[i] - 1./C[i+1]);
72
73 if (x>=H[i] && x<H[i+1])
74 return log10(A[i] + B[i] * exp(-x/C[i]));
75 }
76
77 return -1;
78 }
79};
80
81// ==========================================================================
82
83class MAtmosphere : public MAtmRayleigh
84{
85private:
86 static const Double_t STEPTHETA; // aprox. 1 degree
87
88 // Aerosol number density for 31 heights a.s.l., from 0 to 30 km,
89 // in 1 km steps (units: cm^-3)
90 static const Double_t aero_n[31];
91
92 // Ozone concentration for 51 heights a.s.l., from 0 to 50 km,
93 // in 1 km steps (units: cm/km)
94 static const Double_t oz_conc[51];
95
96 // aerosol_path contains the path integrals for the aerosol number
97 // density (relative to the number density at sea level) between the
98 // observation level and a height h for different zenith angles. The
99 // first index indicate height above sea level in units of 100m, the
100 // second is the zenith angle in degrees.
101 float aerosol_path[301][90];
102
103 // ozone_path contains the path integrals for the ozone concentration
104 // between the observation level and a height h for different zenith
105 // angles. The first index indicate height above sea level in units
106 // of 100m, the second is the zenith angle in degrees.
107 float ozone_path[501][90];
108
109 // Interpolate the graph at wavelength
110 Double_t GetBeta(Double_t wavelength, const TGraph &g) const;
111
112 //MSpline3 *fAbsCoeffOzone;
113 //MSpline3 *fAbsCoeffAerosols;
114
115 TGraph *fAbsCoeffOzone;
116 TGraph *fAbsCoeffAerosols;
117
118public:
119 MAtmosphere(const MCorsikaRunHeader &h) : fAbsCoeffOzone(0), fAbsCoeffAerosols(0)
120 {
121 Init(h);//, "ozone.txt", "aerosols.txt");
122 }
123 MAtmosphere(Float_t obs=0, const char *name1=0, const char *name2=0) : fAbsCoeffOzone(0), fAbsCoeffAerosols(0)
124 {
125 MAtmRayleigh::Init(obs);
126
127 if (name1)
128 InitOzone(name1);
129 if (name2)
130 InitAerosols(name2);
131 }
132 MAtmosphere(const char *name1, const char *name2) : fAbsCoeffOzone(0), fAbsCoeffAerosols(0)
133 {
134 MAtmRayleigh::Init(0);
135
136 if (name1)
137 InitOzone(name1);
138 if (name2)
139 InitAerosols(name2);
140 }
141
142 ~MAtmosphere();
143
144 Float_t GetWavelengthMin() const;
145 Float_t GetWavelengthMax() const;
146
147 Bool_t HasValidOzone() const;
148 Bool_t HasValidAerosol() const;
149
150 Bool_t IsAllValid() const { return IsValid() && HasValidOzone() && HasValidAerosol(); }
151
152 void PreCalcOzone();
153 void PreCalcAerosol();
154 Bool_t InitOzone(const TString name="");
155 Bool_t InitAerosols(const TString name="");
156
157 void Init(const MCorsikaRunHeader &h, const char *name1=0, const char *name2=0)
158 {
159 MAtmRayleigh::Init(h);
160
161 InitOzone(name1);
162 InitAerosols(name2);
163 }
164
165 Double_t CalcOzoneAbsorption(Double_t h, Double_t wavelength, Double_t theta) const;
166 Double_t CalcAerosolAbsorption(Double_t h, Double_t wavelength, Double_t theta) const;
167 Double_t GetTransmission(const MPhotonData &ph) const;
168};
169
170#endif
Note: See TracBrowser for help on using the repository browser.