Commit b296cd78 authored by Scott Griffiths's avatar Scott Griffiths
Browse files

Incremental progress on gdas_entry and msis_entry. Added preliminary msis_reader.

parent 11ecd72b
......@@ -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.")
......
......@@ -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 IntegrateSin(self, lo, hi, eps=1.0E-5):
def integrate_quadratic_sin(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 IntegrateSinExp(self, lo, hi, eps=1.0E-5):
def integrate_quadratic_sin_exp(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.FitQuadSin(grho, self.fFitMin, self.fFitMax, self.fP0Sin, self.fP1Sin, self.fP2Sin, self.fP3Sin, self.fChi2Sin)
self.fit_quadratic_sin(xdata, ydata, xerrs, yerrs, self.fFitMin, self.fFitMax)
Fit(grho, 0, 4, self.fP00to4km, self.fP10to4km, self.fP20to4km, self.fChi20to4km)
FitLin(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)
fit_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 GetHumidity(self, height):
def humidity(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 GetWindSpeed(self, height):
def wind_speed(self, height):
ws_spline = interp1d(self.fHeight, self.fWindSpeed, kind='linear')
return ws_spline(height)
def GetWindDir(self, height):
def wind_dir(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)