Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cta-array-elements
ccf
LIDAR_Analysis
Commits
b296cd78
Commit
b296cd78
authored
May 10, 2017
by
Scott Griffiths
Browse files
Incremental progress on gdas_entry and msis_entry. Added preliminary msis_reader.
parent
11ecd72b
Changes
4
Show whitespace changes
Inline
Side-by-side
atca_wizard.py
View file @
b296cd78
...
...
@@ -47,6 +47,7 @@ class AtcaWizard:
self
.
fMSIS
=
None
self
.
fGDAS
=
None
# TODO: This function needs revision
def
LoadWeather
(
self
,
filename
=
"WS2013.root"
):
if
self
.
fWeather
:
delete
self
.
fWeather
...
...
@@ -87,6 +88,7 @@ class AtcaWizard:
print
(
args
[
0
],
" "
,
args
[
1
],
" "
,
args
[
2
])
return
(
args
)
# TODO: This function needs revision
def
LoadMSIS
(
self
,
filename
=
"msis2013.root"
,
verbose
=
False
):
if
self
.
fMSIS
:
delete
self
.
fMSIS
...
...
@@ -121,6 +123,7 @@ class AtcaWizard:
if
verbose
:
self
.
fMSIS
.
Print
()
# TODO: This function needs revision
def
CreateGDAS
(
self
,
files
=
"gdas1.*13.w*_magic1"
,
outfile
=
"GDAS1.root"
):
tlist
=
[]
MGDASFileRead
r
(
files
)
...
...
@@ -132,6 +135,7 @@ class AtcaWizard:
tlist
.
append
(
w
)
w
.
Close
()
# TODO: This function needs revision
def
LoadGDAS
(
self
,
filename
=
"gdas2013_magic1.root"
,
verbose
=
False
):
if
self
.
fGDAS
:
delete
self
.
fGDAS
...
...
@@ -170,6 +174,7 @@ class AtcaWizard:
b
=
self
.
fGDAS
.
GetBranch
(
"MGDASEntry."
)
b
.
SetAutoDelete
(
False
)
# TODO: This function needs revision
def
GetWeather
(
self
,
mjd
,
verbose
=
False
):
if
not
self
.
fWeather
:
raise
RuntimeError
(
"No weather file 'WS*.root' has been loaded, please use LoadWeather first."
)
...
...
@@ -224,6 +229,7 @@ class AtcaWizard:
dust
=
args
[
10
]
return
temperature
,
pressure
,
humidity
,
dust
# TODO: This function needs revision
def
GetMSIS
(
self
,
mjd
,
verbose
=
False
):
if
not
self
.
fMSIS
:
raise
RuntimeError
(
"No MSIS file 'MSIS*.root' has been loaded, please use LoadMSIS first."
)
...
...
@@ -268,6 +274,7 @@ class AtcaWizard:
break
return
msis_entry
# TODO: This function needs revision
def
GetGDAS
(
self
,
mjd
,
verbose
=
False
):
if
not
self
.
fGDAS
:
raise
RuntimeError
(
"No GDAS file 'GDAS*.root' has been loaded, please use LoadGDAS first."
)
...
...
gdas_entry.py
View file @
b296cd78
...
...
@@ -17,6 +17,9 @@ import numpy as np
def
linear_model
(
x
,
c0
,
c1
):
return
c0
+
c1
*
x
/
10
def
quadratic_model
(
x
,
c0
,
c1
,
c2
):
return
c0
+
c1
*
x
/
10
+
c2
*
x
*
x
/
100
def
cubic_model
(
x
,
c0
,
c1
,
c2
,
c3
):
return
c0
+
c1
*
x
/
10
+
c2
*
x
*
x
/
100
+
c3
*
x
*
x
*
x
/
1000
...
...
@@ -38,12 +41,12 @@ class GDASEntry:
vertical_levels
=
[
1000
,
975
,
950
,
925
,
900
,
850
,
800
,
750
,
700
,
650
,
600
,
550
,
500
,
450
,
400
,
350
,
300
,
250
,
200
,
150
,
100
,
50
,
20
]
TF1
self
.
fLin
(
"flin"
,
"[0] + [1]*x/10"
,
0
,
self
.
gkHeightLast
)
TF1
self
.
fThird
(
"fThird"
,
"[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000"
,
0
,
self
.
gkHeightLast
)
TF1
self
.
fFourth
(
"fFourth"
,
"[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000 + [4]*x*x*x*x/100000"
,
0
,
self
.
gkHeightLast
)
TF1
self
.
fFifth
(
"fFifth"
,
"[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000 + [4]*x*x*x*x/100000 + [5]*x*x*x*x*x/10000000"
,
0
,
self
.
gkHeightLast
)
TF1
self
.
fQuadSin
(
"fQuadSin"
,
"[0] + [1]*x/10 + [2]*x*x/100 + [3]*sin([4]*0.4*(x - [5]))*(x - [5])/1000"
,
0
,
self
.
gkHeightLast
)
TF1
self
.
fQuadSinExp
(
"fQuadSinExp"
,
"exp([0] + [1]*x/10 + [2]*x*x/100 + [3]*sin([4]*0.4*(x - [5]))*(x - [5])/1000)"
,
0
,
self
.
gkHeightLast
)
#
TF1 self.fLin("flin", "[0] + [1]*x/10", 0, self.gkHeightLast)
#
TF1 self.fThird("fThird", "[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000", 0, self.gkHeightLast)
#
TF1 self.fFourth("fFourth", "[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000 + [4]*x*x*x*x/100000", 0, self.gkHeightLast)
#
TF1 self.fFifth("fFifth", "[0] + [1]*x/10 + [2]*x*x/100 + [3]*x*x*x/1000 + [4]*x*x*x*x/100000 + [5]*x*x*x*x*x/10000000", 0, self.gkHeightLast)
#
TF1 self.fQuadSin("fQuadSin", "[0] + [1]*x/10 + [2]*x*x/100 + [3]*sin([4]*0.4*(x - [5]))*(x - [5])/1000", 0, self.gkHeightLast)
#
TF1 self.fQuadSinExp("fQuadSinExp", "exp([0] + [1]*x/10 + [2]*x*x/100 + [3]*sin([4]*0.4*(x - [5]))*(x - [5])/1000)", 0, self.gkHeightLast)
def
__init__
(
self
):
self
.
dHeight
=
0.01
...
...
@@ -150,20 +153,8 @@ class GDASEntry:
self
.
fLatitude
=
obs
.
GetLatitudeDeg
()
self
.
fLongitude
=
obs
.
GetLongitudeDeg
()
def
getp
(
self
,
idx
):
return
self
.
vertical_levels
[
idx
-
1
]
def
convert_wind
(
self
,
u
,
v
):
"""
Convert to meteorological wind directions.
Winds coming from North: theta = 0, coming from East: theta = 90
"""
wind_speed
=
sqrt
(
u
*
u
+
v
*
v
)
wind_dir
=
np
.
rad2deg
(
atan2
(
v
,
u
))
wind_dir
=
(
270
-
wind_dir
)
%
360
return
wind_speed
,
wind_dir
def
FillProfile
(
self
,
data
,
version
=
0
):
def
fill_profile
(
self
,
data
,
version
=
0
):
n
=
sscanf
(
line
.
Data
(),
"%d %n"
,
height_idx
,
len
)
if
n
!=
1
:
print
(
line
)
...
...
@@ -237,32 +228,26 @@ class GDASEntry:
self
.
fWindSpeed
[
height_idx
]
=
windsp
self
.
fWindDir
[
height_idx
]
=
winddir
def
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
):
def
getp
(
self
,
idx
):
"""
Select a subset of xdata, ydata for a given range of x values
.
Gets the pressure for a given GDAS vertical level index
.
Args:
xdata, ydata : numpy arrays with x,y data
lower, upper : bounds for x (inclusive)
GDAS records data for the ground (vertical level = 0) and 23 pressure
surfaces, which are indexed from 1-23.
Returns:
xdata, ydata over the interval lower <= x <= upper
Returns the pressure in hPa for the given vertical level index.
"""
if
lower
is
None
:
lower
=
-
np
.
inf
if
upper
is
None
:
upper
=
np
.
inf
idx
=
np
.
where
((
x
>=
lower
)
&
(
x
<=
upper
))
return
xdata
[
idx
],
ydata
[
idx
]
return
self
.
vertical_levels
[
idx
-
1
]
def
FitLin
(
self
,
xdata
,
ydata
,
lower
=
None
,
upper
=
None
):
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
linear_model
,
xdata
,
ydata
)
popt
[
1
]
/=
10
chi2
=
np
.
sum
((
linear_fit
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
return
popt
,
chi2
/
ndf
def
convert_wind
(
self
,
u
,
v
):
"""
Convert to meteorological wind directions.
Winds coming from North: theta = 0, coming from East: theta = 90
"""
wind_speed
=
sqrt
(
u
*
u
+
v
*
v
)
wind_dir
=
np
.
rad2deg
(
atan2
(
v
,
u
))
wind_dir
=
(
270
-
wind_dir
)
%
360
return
wind_speed
,
wind_dir
def
EvalOverlap
(
self
,
h
):
"""
...
...
@@ -280,21 +265,11 @@ class GDASEntry:
return
0
return
exp
(
self
.
fP0Overlap
)
/
self
.
fP1Overlap
*
(
exp
(
hi
*
self
.
fP1Overlap
)
-
exp
(
lo
*
self
.
fP1Overlap
))
def
FitQuadSin
(
self
,
xdata
,
ydata
,
lower
=
None
,
upper
=
None
):
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
param_lower_bounds
=
[
-
np
.
inf
,
-
np
.
inf
,
-
0.45
,
-
25
,
0.3
,
-
30
]
param_upper_bounds
=
[
np
.
inf
,
np
.
inf
,
0.2
,
25
,
1.8
,
15
]
bounds
=
(
param_lower_bounds
,
param_upper_bounds
)
popt
,
pcov
=
curve_fit
(
quadratic_sin_model
,
xdata
,
ydata
,
bounds
=
bounds
)
popt
[
1
]
/=
10
popt
[
2
]
/=
100
popt
[
3
]
/=
1000
chi2
=
np
.
sum
((
quadratic_sin_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
return
popt
,
chi2
/
ndf
def
InitFunctions
(
self
):
"""
Initializes function parameters, which are needed for fit_quintic,
fit_quadratic_sin, integrate_quadratic_sin, and integrate_quadratic_sin_exp (and maybe others?).
"""
if
self
.
fP0Sin
<
-
98
and
self
.
fP1Sin
<
-
98
and
self
.
fP2Sin
<
-
98
and
self
.
fP3Sin
<
-
98
:
return
...
...
@@ -324,23 +299,21 @@ class GDASEntry:
if
not
self
.
fIsInit
:
self
.
InitFunctions
()
return
self
.
fQuadSin
.
Eval
(
h
)
# return res == 0. ? -99. : res
def
EvalFifth
(
self
,
h
):
if
not
self
.
fIsInit
:
self
.
InitFunctions
()
return
self
.
fFifth
.
Eval
(
h
)
# return res == 0. ? -99. : res
def
I
ntegrate
S
in
(
self
,
lo
,
hi
,
eps
=
1.0E-5
):
def
i
ntegrate
_quadratic_s
in
(
self
,
lo
,
hi
,
eps
=
1.0E-5
):
if
not
self
.
fIsInit
:
self
.
InitFunctions
()
params
=
None
# use previously set parameters
res
=
self
.
fQuadSin
.
Integral
(
lo
,
hi
,
params
,
eps
)
res
=
self
.
fQuadSin
.
Integral
(
lo
,
hi
,
eps
)
return
res
# == 0. ? -99. : res
return
res
def
I
ntegrate
SinE
xp
(
self
,
lo
,
hi
,
eps
=
1.0E-5
):
def
i
ntegrate
_quadratic_sin_e
xp
(
self
,
lo
,
hi
,
eps
=
1.0E-5
):
if
hi
>
25
:
return
-
99
if
not
self
.
fIsInit
:
...
...
@@ -375,73 +348,117 @@ class GDASEntry:
else
:
return
self
.
EvalSin
(
h_c
)
-
2
/
costheta
*
Rayleigh
.
LIDAR_ratio_mol
*
beta_mol_0
*
self
.
IntegrateFull
(
hlo_c
,
h_c
)
*
1000
# convert from km to m
def
FitQuad
(
g
,
low
,
up
):
fQuad
.
SetParameter
(
0
,
0.
);
fQuad
.
SetParameter
(
1
,
-
0.95
);
fQuad
.
SetParameter
(
2
,
-
0.17
);
g
.
Fit
(
self
.
fThird
,
o
,
go
,
low
,
up
)
p0
=
self
.
fThird
.
GetParameter
(
0
)
p1
=
self
.
fThird
.
GetParameter
(
1
)
/
10
p2
=
self
.
fThird
.
GetParameter
(
2
)
/
100
chi2
=
self
.
fThird
.
GetChisquare
()
/
self
.
fThird
.
GetNDF
()
return
p0
,
p1
,
p2
,
p3
,
chi2
def
FitThird
(
g
,
low
,
up
):
fThird
.
SetParameter
(
0
,
fQuad
.
GetParameter
(
0
));
fThird
.
SetParameter
(
1
,
fQuad
.
GetParameter
(
1
));
fThird
.
SetParameter
(
2
,
fQuad
.
GetParameter
(
2
));
fThird
.
SetParameter
(
3
,
0.
);
g
.
Fit
(
self
.
fThird
,
o
,
go
,
low
,
up
)
p0
=
self
.
fThird
.
GetParameter
(
0
)
p1
=
self
.
fThird
.
GetParameter
(
1
)
/
10
p2
=
self
.
fThird
.
GetParameter
(
2
)
/
100
p3
=
self
.
fThird
.
GetParameter
(
3
)
/
1000
chi2
=
self
.
fThird
.
GetChisquare
()
/
self
.
fThird
.
GetNDF
()
return
p0
,
p1
,
p2
,
p3
,
chi2
def
FitFourth
(
g
,
low
,
up
):
fFourth
.
SetParameter
(
0
,
fThird
.
GetParameter
(
0
));
fFourth
.
SetParameter
(
1
,
fThird
.
GetParameter
(
1
));
fFourth
.
SetParameter
(
2
,
fThird
.
GetParameter
(
2
));
fFourth
.
SetParameter
(
3
,
fThird
.
GetParameter
(
3
));
fFourth
.
SetParameter
(
4
,
0.
);
g
.
Fit
(
self
.
fFourth
,
o
,
go
,
low
,
up
)
p0
=
self
.
fFourth
.
GetParameter
(
0
)
p1
=
self
.
fFourth
.
GetParameter
(
1
)
/
10
p2
=
self
.
fFourth
.
GetParameter
(
2
)
/
100
p3
=
self
.
fFourth
.
GetParameter
(
3
)
/
1000
p4
=
self
.
fFourth
.
GetParameter
(
4
)
/
100000
chi2
=
self
.
fFourth
.
GetChisquare
()
/
self
.
fFourth
.
GetNDF
()
return
p0
,
p1
,
p2
,
p3
,
p4
,
chi2
def
FitFifth
(
g
,
low
,
up
):
fFifth
.
SetParameter
(
0
,
fFourth
.
GetParameter
(
0
));
fFifth
.
SetParameter
(
1
,
fFourth
.
GetParameter
(
1
));
fFifth
.
SetParameter
(
2
,
fFourth
.
GetParameter
(
2
));
fFifth
.
SetParameter
(
3
,
fFourth
.
GetParameter
(
3
));
fFifth
.
SetParameter
(
4
,
0.
);
fFifth
.
SetParameter
(
5
,
0.
);
g
.
Fit
(
self
.
fFifth
,
o
,
go
,
low
,
up
)
p0
=
self
.
fFifth
.
GetParameter
(
0
)
p1
=
self
.
fFifth
.
GetParameter
(
1
)
/
10
p2
=
self
.
fFifth
.
GetParameter
(
2
)
/
100
p3
=
self
.
fFifth
.
GetParameter
(
3
)
/
1000
p4
=
self
.
fFifth
.
GetParameter
(
4
)
/
100000
p5
=
self
.
fFifth
.
GetParameter
(
5
)
/
10000000
chi2
=
self
.
fFifth
.
GetChisquare
()
/
self
.
fFifth
.
GetNDF
()
return
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
chi2
def
fit_linear
(
self
,
xdata
,
ydata
,
xerrs
,
yerrs
,
lower
=
None
,
upper
=
None
):
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
linear_model
,
xdata
,
ydata
)
chi2
=
np
.
sum
((
linear_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
popt
[
1
]
/=
10
return
popt
,
chi2
/
ndf
def
fit_quadratic
(
self
,
xdata
,
ydata
,
xerrs
,
yerrs
,
lower
=
None
,
upper
=
None
):
param_guess
=
[
0
,
-
0.95
,
-
0.17
]
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
quadratic_model
,
xdata
,
ydata
,
p0
=
param_guess
)
chi2
=
np
.
sum
((
quadratic_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
# popt[1] /= 10
# popt[2] /= 100
return
popt
,
chi2
/
ndf
def
fit_cubic
(
self
,
xdata
,
ydata
,
xerrs
,
yerrs
,
lower
=
None
,
upper
=
None
):
param_guess
=
self
.
fQuad
+
[
0
]
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
cubic_model
,
xdata
,
ydata
,
p0
=
param_guess
)
chi2
=
np
.
sum
((
cubic_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
# popt[1] /= 10
# popt[2] /= 100
# popt[3] /= 1000
return
popt
,
chi2
/
ndf
def
fit_quartic
(
self
,
xdata
,
ydata
,
xerrs
,
yerrs
,
lower
=
None
,
upper
=
None
):
param_guess
=
self
.
fCubic
+
[
0
]
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
cubic_model
,
xdata
,
ydata
,
p0
=
param_guess
)
chi2
=
np
.
sum
((
cubic_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
# popt[1] /= 10
# popt[2] /= 100
# popt[3] /= 1000
# popt[4] /= 100000
return
popt
,
chi2
/
ndf
def
fit_quintic
(
g
,
low
,
up
):
param_guess
=
self
.
fQuartic
[:
-
1
]
+
[
0
,
0
]
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
popt
,
pcov
=
curve_fit
(
cubic_model
,
xdata
,
ydata
,
p0
=
param_guess
)
chi2
=
np
.
sum
((
cubic_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
# popt[1] /= 10
# popt[2] /= 100
# popt[3] /= 1000
# popt[4] /= 100000
# popt[4] /= 10000000
return
popt
,
chi2
/
ndf
def
fit_quadratic_sin
(
self
,
xdata
,
ydata
,
xerrs
,
yerrs
,
lower
=
None
,
upper
=
None
):
if
any
((
lower
,
upper
)):
xdata
,
ydata
=
self
.
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
)
param_lower_bounds
=
[
-
np
.
inf
,
-
np
.
inf
,
-
0.45
,
-
25
,
0.3
,
-
30
]
param_upper_bounds
=
[
np
.
inf
,
np
.
inf
,
0.2
,
25
,
1.8
,
15
]
bounds
=
(
param_lower_bounds
,
param_upper_bounds
)
popt
,
pcov
=
curve_fit
(
quadratic_sin_model
,
xdata
,
ydata
,
bounds
=
bounds
)
chi2
=
np
.
sum
((
quadratic_sin_model
(
xdata
,
*
popt
)
-
ydata
)
**
2
)
ndf
=
len
(
xdata
)
-
len
(
popt
)
# popt[1] /= 10
# popt[2] /= 100
# popt[3] /= 1000
return
popt
,
chi2
/
ndf
def
select_in_xrange
(
xdata
,
ydata
,
lower
,
upper
):
"""
Select a subset of xdata, ydata for a given range of x values.
Args:
xdata, ydata : numpy arrays with x,y data
lower, upper : bounds for x (inclusive)
Returns:
xdata, ydata over the interval lower <= x <= upper
"""
if
lower
is
None
:
lower
=
-
np
.
inf
if
upper
is
None
:
upper
=
np
.
inf
idx
=
np
.
where
((
x
>=
lower
)
&
(
x
<=
upper
))
return
xdata
[
idx
],
ydata
[
idx
]
# TODO: THIS FUNCTION NEEDS REVISION
def
FitProfiles
(
self
):
grho
=
new
TGraphErrors
(
self
.
gkNheights
,
self
.
fHeight
.
GetArray
(),
self
.
fLogDensity
.
GetArray
(),
self
.
fHeightErr
.
GetArray
(),
self
.
fLogDensityErr
.
GetArray
())
"""Fit density profiles."""
xdata
=
self
.
fHeight
ydata
=
self
.
fLogDensity
xerr
=
self
.
fHeightErr
yerr
=
self
.
fLogDensityErr
# grho = new TGraphErrors(self.gkNheights, self.fHeight.GetArray(), self.fLogDensity.GetArray(), self.fHeightErr.GetArray(), self.fLogDensityErr.GetArray())
# self.fit_quadratic(grho, self.fFitMin, self.fFitMax, self.fP0Quad, self.fP1Quad, self.fP2Quad, self.fChi2Quad)
# self.fit_cubic(grho, self.fFitMin, self.fFitMax, self.fP0Tot, self.fP1Tot, self.fP2Tot, self.fP3Tot, self.fChi2Tot)
# self.fit_quartic(grho, self.fFitMin, self.fFitMax, self.fP0Fourth, self.fP1Fourth, self.fP2Fourth, self.fP3Fourth, self.fP4Fourth, self.fChi2Fourth)
# self.fit_quintic(grho, self.fFitMin, self.fFitMax, self.fP0Fifth, self.fP1Fifth, self.fP2Fifth, self.fP3Fifth, self.fP4Fifth, self.fP5Fifth, self.fChi2Fifth)
self
.
fit_quadratic
(
xdata
,
ydata
,
xerrs
,
yerrs
,
self
.
fFitMin
,
self
.
fFitMax
)
self
.
fit_cubic
(
xdata
,
ydata
,
xerrs
,
yerrs
,
self
.
fFitMin
,
self
.
fFitMax
)
self
.
fit_quartic
(
xdata
,
ydata
,
xerrs
,
yerrs
,
self
.
fFitMin
,
self
.
fFitMax
)
self
.
fit_quintic
(
xdata
,
ydata
,
xerrs
,
yerrs
,
self
.
fFitMin
,
self
.
fFitMax
)
self
.
FitQuad
(
grho
,
self
.
fFitMin
,
self
.
fFitMax
,
self
.
fP0Quad
,
self
.
fP1Quad
,
self
.
fP2Quad
,
self
.
fChi2Quad
)
self
.
FitThird
(
grho
,
self
.
fFitMin
,
self
.
fFitMax
,
self
.
fP0Tot
,
self
.
fP1Tot
,
self
.
fP2Tot
,
self
.
fP3Tot
,
self
.
fChi2Tot
)
self
.
FitFourth
(
grho
,
self
.
fFitMin
,
self
.
fFitMax
,
self
.
fP0Fourth
,
self
.
fP1Fourth
,
self
.
fP2Fourth
,
self
.
fP3Fourth
,
self
.
fP4Fourth
,
self
.
fChi2Fourth
)
self
.
FitFifth
(
grho
,
self
.
fFitMin
,
self
.
fFitMax
,
self
.
fP0Fifth
,
self
.
fP1Fifth
,
self
.
fP2Fifth
,
self
.
fP3Fifth
,
self
.
fP4Fifth
,
self
.
fP5Fifth
,
self
.
fChi2Fifth
)
self
.
fQuadSin
.
SetParameter
(
0
,
self
.
fQuad
.
GetParameter
(
0
))
self
.
fQuadSin
.
SetParameter
(
1
,
self
.
fQuad
.
GetParameter
(
1
))
...
...
@@ -450,11 +467,11 @@ class GDASEntry:
self
.
fQuadSin
.
SetParameter
(
4
,
1.0
)
self
.
fQuadSin
.
SetParameter
(
5
,
1.5
)
self
.
F
it
Q
uad
Sin
(
grho
,
self
.
fFitMin
,
self
.
fFitMax
,
self
.
fP0Sin
,
self
.
fP1Sin
,
self
.
fP2Sin
,
self
.
f
P3S
in
,
self
.
f
Chi2Sin
)
self
.
f
it
_q
uad
ratic_sin
(
xdata
,
ydata
,
xerrs
,
yerrs
,
self
.
f
FitM
in
,
self
.
f
FitMax
)
Fit
(
grho
,
0
,
4
,
self
.
fP00to4km
,
self
.
fP10to4km
,
self
.
fP20to4km
,
self
.
fChi20to4km
)
F
it
Lin
(
grho
,
2
,
5
,
self
.
fP0Overlap
,
self
.
fP1Overlap
,
dummy
,
self
.
fChi2Overlap
)
Fit
(
grho
,
10
,
40
,
self
.
fP010to40km
,
self
.
fP110to40km
,
self
.
fP210to40km
,
self
.
fChi210to40km
)
MSISEntry
.
Fit
(
grho
,
0
,
4
,
self
.
fP00to4km
,
self
.
fP10to4km
,
self
.
fP20to4km
,
self
.
fChi20to4km
)
f
it
_linear
(
xdata
,
ydata
,
xerrs
,
yerrs
,
2
,
5
)
MSISEntry
.
Fit
(
grho
,
10
,
40
,
self
.
fP010to40km
,
self
.
fP110to40km
,
self
.
fP210to40km
,
self
.
fChi210to40km
)
height_MAGIC
=
AtcaWizard
.
H0_WS
...
...
@@ -472,282 +489,38 @@ class GDASEntry:
self
.
fMassOverburden
=
self
.
fPressure
*
AtcaWizard
.
mbar2gcm2
self
.
fLogMassOverburden
=
[
log
(
x
)
if
x
>
0
else
-
1
for
x
in
self
.
fMassOverburden
]
def
GetH
umidity
(
self
,
height
):
def
h
umidity
(
self
,
height
):
RH_spline
=
interp1d
(
self
.
fHeight
,
self
.
fRH
,
kind
=
'linear'
)
return
RH_spline
(
height
)
def
GetPressure
(
self
,
height
):
def
pressure
(
self
,
height
):
"""
Interpolate logarithm of pressure, which behaves more linearly than
exponential decay.
"""
log_pressure
=
np
.
log
(
self
.
fPressure
)
log_p_spline
=
interp1d
(
self
.
fHeight
,
log_pressure
,
kind
=
'linear'
)
return
exp
(
log_p_spline
(
height
))
def
GetW
ind
S
peed
(
self
,
height
):
def
w
ind
_s
peed
(
self
,
height
):
ws_spline
=
interp1d
(
self
.
fHeight
,
self
.
fWindSpeed
,
kind
=
'linear'
)
return
ws_spline
(
height
)
def
GetW
ind
D
ir
(
self
,
height
):
def
w
ind
_d
ir
(
self
,
height
):
wd_spline
=
interp1d
(
self
.
fHeight
,
self
.
fWindDir
,
kind
=
'linear'
)
return
wd_spline
(
height
)
# TODO: fix huge plotting function of DOOOM!!!
def
Draw
(
self
,
newfit
=
True
,
lowlim
=
2.2
,
uplim
=
19
):
def
refractive_index
(
self
,
height
,
wavelength
):
"""
Draw allows the following options:
- newfit: fit the data new (otherwise use the existing fit solutions =default)
- lowlim=XX: use a different lower limit fit range to the density profile
- uplim=Xx: use a different upper limit fit range to the density profile
Wrapper for Rayleigh.calculate_n().
"""
c
=
new
TCanvas
(
"c"
,
"c"
,
1000
,
1500
)
c
.
Divide
(
2
,
3
)
c
.
cd
(
1
)
grho
=
new
TGraphErrors
(
self
.
gkNheights
,
self
.
fHeight
.
GetArray
(),
self
.
fLogDensity
.
GetArray
(),
self
.
fHeightErr
.
GetArray
(),
self
.
fLogDensityErr
.
GetArray
())
grho
.
SetTitle
(
"log(density)altitude a.s.l. (km)ln (n / n_s)"
)
grho
.
SetMarkerStyle
(
7
)
grho
.
SetMarkerSize
(
8
)
grho
.
SetLineWidth
(
5
)
grho
.
Draw
(
"AP"
)
foverlap
=
new
TF1
(
"foverlap"
,
"[0]+[1]*x/10"
,
2
,
5
)
foverlap
.
SetLineColor
(
kRed
)
foverlap
.
SetParameter
(
0
,
self
.
fP0Overlap
)
foverlap
.
SetParameter
(
1
,
self
.
fP1Overlap
*
10
)
if
newfit
:
grho
.
Fit
(
foverlap
,
"RWQ"
,
"same"
,
lowlim
,
uplim
)
else
:
foverlap
.
Draw
(
"same"
)
fquad
=
new
TF1
(
"fquad"
,
"[0]+[1]*x/10+[2]*x*x/100."
,
0
,
self
.
gkHeightLast
)
fquad
.
SetLineColor
(
kBlue
)
fquad
.
SetParameter
(
0
,
self
.
fP0Quad
)
fquad
.
SetParameter
(
1
,
self
.
fP1Quad
*
10
)
fquad
.
SetParameter
(
2
,
self
.
fP2Quad
*
100
)
if
newfit
:
p0
,
p1
,
p2
,
chi2
=
Fit
(
grho
,
lowlim
,
uplim
,
"RWQM+N"
,
""
)
print
(
p0
,
" "
,
p1
,
" "
,
p2
,
" #chi^2 "
,
chi2
)
fquad
.
SetParameter
(
0
,
p0
)
fquad
.
SetParameter
(
1
,
p1
*
10
)
fquad
.
SetParameter
(
2
,
p2
*
100
)
fquad
.
Draw
(
"same"
)
else
:
fquad
.
Draw
(
"same"
)
self
.
fFourth
.
SetLineColor
(
kViolet
+
2
)
self
.
fFourth
.
SetParameter
(
0
,
self
.
fP0Fourth
)
self
.
fFourth
.
SetParameter
(
1
,
self
.
fP1Fourth
*
10
)
self
.
fFourth
.
SetParameter
(
2
,
self
.
fP2Fourth
*
100
)
self
.
fFourth
.
SetParameter
(
3
,
self
.
fP3Fourth
*
1000
)
self
.
fFourth
.
SetParameter
(
4
,
self
.
fP4Fourth
*
100000
)
if
newfit
:
p0
,
p1
,
p2
,
p3
,
p4
,
chi2
=
FitFourth
(
grho
,
lowlim
,
uplim
,
"RWQM+"
,
"same"
)
print
(
p0
,
" "
,
p1
,
" "
,
p2
,
" "
,
p3
,
" "
,
p4
,
" #chi^2 "
,
chi2
)
else
:
self
.
fFourth
.
Draw
(
"same"
)
p
=
self
.
pressure
(
height
)
T
=
MSISEntry
.
GetTemperature
(
height
)
# TODO: FIXME! This can't be correct!
RH
=
self
.
humidity
(
height
)
return
Rayleigh
.
calculate_n
(
wavelength
,
p
,
T
,
RH
)
self
.
fFifth
.
SetLineColor
(
kGreen
+
1
)
self
.
fFifth
.
SetParameter
(
0
,
self
.
fP0Fifth
)
self
.
fFifth
.
SetParameter
(
1
,
self
.
fP1Fifth
*
10
)
self
.
fFifth
.
SetParameter
(
2
,
self
.
fP2Fifth
*
100
)
self
.
fFifth
.
SetParameter
(
3
,
self
.
fP3Fifth
*
1000
)
self
.
fFifth
.
SetParameter
(
4
,
self
.
fP4Fifth
*
100000
)
self
.
fFifth
.
SetParameter
(
5
,
self
.
fP5Fifth
*
10000000
)
if
newfit
:
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
chi2
=
FitFifth
(
grho
,
lowlim
,
uplim
,
"RWQM+"
,
"same"
)
print
(
p0
,
" "
,
p1
,
" "
,
p2
,
" "
,
p3
,
" "
,
p4
,
" "
,
p5
,
" #chi^2 "
,
chi2
)
else
:
self
.
fFifth
.
Draw
(
"same"
)
self
.
fQuadSin
.
SetLineColor
(
kOrange
+
1
)
self
.
fQuadSin
.
SetParameter
(
0
,
self
.
fP0Sin
)
self
.
fQuadSin
.
SetParameter
(
1
,
self
.
fP1Sin
*
10
)
self
.
fQuadSin
.
SetParameter
(
2
,
self
.
fP2Sin
*
100
)
self
.
fQuadSin
.
SetParameter
(
3
,
self
.
fP3Sin
*
1000
)
self
.
fQuadSin
.
SetParameter
(
4
,
self
.
fP4Sin
)
self
.
fQuadSin
.
SetParameter
(
5
,
self
.
fP5Sin
)
if
newfit
:
p0
,
p1
,
p2
,
p3
,
chi2
=
FitQuadSin
(
grho
,
lowlim
,
uplim
,
"RWMQ+"
,
"same"
)
print
(
p0
,
" "
,
p1
,
" "
,
p2
,
" #chi^2 "
,
self
.
fChi2Sin
)
else
:
self
.
fQuadSin
.
Draw
(
"same"
)
leg
=
new
TLegend
(
0.6
,
0.55
,
0.9
,
0.9
,
""
,
"brNDC"
)
leg
.
SetFillColor
(
0
)
leg
.
SetBorderSize
(
1
)
leg
.
AddEntry
(
foverlap
,
"Overlap Region Fit"
,
"l"
)
leg
.
AddEntry
(
fquad
,
"Pol. 2^nd order"
,
"l"
)
leg
.
AddEntry
(
self
.
fFourth
,
"Pol. 4^th order"
,
"l"
)
leg
.
AddEntry
(
self
.
fFifth
,
"Pol. 5^th order"
,
"l"
)
leg
.
AddEntry
(
self
.
fQuadSin
,
"f(x)"
,
"l"
)
leg
.
Draw
()
gPad
.
SetGridx
()
gPad
.
SetGridy
()
c
.
cd
(
2
)
logdcorr
[
self
.
gkNheights
]
for
i
in
range
(
self
.
gkNheights
):
logdcorr
[
i
]
=
self
.
fLogDensity
[
i
]
-
self
.
fP1Overlap
*
fHeight
[
i
]
grhod
=
new
TGraphErrors
(
self
.
gkNheights
,
self
.
fHeight
.
GetArray
(),
logdcorr
,
self
.
fHeightErr
.
GetArray
(),
self
.
fLogDensityErr
.
GetArray
())
grhod
.
SetTitle
(
"log(density) (w.r.t. exponential)altitude a.s.l. (km)ln (n / n_s) + %.2f*altitude"
%
-
fP1Overlap
)
grhod
.
SetMarkerStyle
(
7
)
grhod
.
SetMarkerSize
(
8
)
grhod
.
SetLineWidth
(
5
)
grhod
.
Draw
(
"AP"
)
self
.
fQuadSinC
=
self
.
fQuadSin
.
Clone
(
"fQuadSinC"
)
self
.
fQuadSinC
.
SetParameter
(
1
,
self
.
fQuadSinC
.
GetParameter
(
1
)
-
self
.
fP1Overlap
*
10
)
self
.
fQuadSinC
.
Draw
(
"same"
)
self
.
fQuadC
=
fquad
.
Clone
(
"fQuadC"
)
self
.
fQuadC
.
SetParameter
(
1
,
fquad
.
GetParameter
(
1
)
-
self
.
fP1Overlap
*
10
)
self
.
fQuadC
.
Draw
(
"same"
)
self
.
fFourthC
=
self
.
fFourth
.
Clone
(
"fFourthC"
)
self
.
fFourthC
.
SetParameter
(
1
,
(
self
.
fP1Fourth
-
self
.
fP1Overlap
)
*
10
)
self
.
fFourthC
.
Draw
(
"same"
)
self
.
fFifthC
=
self
.
fFifth
.
Clone
(
"fFifthC"
)
self
.
fFifthC
.
SetParameter
(
1
,
(
self
.
fP1Fifth
-
self
.
fP1Overlap
)
*
10
)
self
.
fFifthC
.
Draw
(
"same"
)
self
.
fLinC
=
foverlap
.
Clone
(
"fLinC"
)
self
.
fLinC
.
SetParameter
(
0
,
self
.
fP0Overlap
)
self
.
fLinC
.
SetParameter
(
1
,
0
)
self
.
fLinC
.
Draw
(
"same"
)
leg2
=
new
TLegend
(
0.15
,
0.15
,
0.5
,
0.5
,
""
,
"brNDC"
)
leg2
.
SetFillColor
(
0
)
leg2
.
SetBorderSize
(
1
)
leg2
.
AddEntry
(
self
.
fLinC
,
"Overlap Region Fit"
,
"l"
)
leg2
.
AddEntry
(
self
.
fQuadC
,
"Pol. 2^nd order"
,
"l"
)
leg2
.
AddEntry
(
self
.
fFourthC
,
"Pol. 4^th order"
,
"l"
)
leg2
.
AddEntry
(
self
.
fFifthC
,
"Pol. 5^th order"
,
"l"
)
leg2
.
AddEntry
(
self
.
fQuadSinC
,
"f(x)"
,
"l"
)
leg2
.
Draw
()
gPad
.
SetGridx
()
gPad
.
SetGridy
()
c
.
cd
(
3
)
gtemp
=
new
TGraph
(
self
.
fHeight
.
GetSize
(),
self
.
fHeight
.
GetArray
(),
self
.
fTemperature
.
GetArray
())
gtemp
.
SetTitle
(
"Temperaturealtitude a.s.l. (km)T (K)"
)
gtemp
.
SetMarkerStyle
(
8
)
gtemp
.
SetMarkerSize
(
1
)