ported slalib.sla_refro, some refactoring

This commit is contained in:
yosata committed 2020-08-05 11:37:49 +02:00
1 parent 83d0c9ea45
commit c1f94e4d95
9 files changed
+1241 -234

No files matched your search

+91 -13
View File
@@ -9,7 +9,7 @@ import numpy as np
atmospheric dispersion, given a set of conditions.
'''
def BarrellAndSears(l, T=288.15, p=101325, H=0):
def BarrellAndSears(l, T=288.15, p=101325, RH=0):
'''
From Barrell & Sears, 1939
Equation 7.7, page 52
@@ -24,7 +24,7 @@ def BarrellAndSears(l, T=288.15, p=101325, H=0):
Temperature in Kelvin
p : float
Atmospheric pressure in Pascal
H : float
RH : float
Relative humidity (0=<H=<1)
Returns
@@ -34,10 +34,11 @@ def BarrellAndSears(l, T=288.15, p=101325, H=0):
'''
T = K2C(T)
P = hPA2mmHg(p/100)
R = (0.378125 + 0.0021414 / l**2 + 0.00001793 / l**4) * (P*(1 + (1.049 - 0.0157*T) * P * 1e-6)/(1 + 0.003661*T)) - (0.0624 - 0.000680 / l**2) * H / (1 + 0.003661*T)
R = (0.378125 + 0.0021414 / l**2 + 0.00001793 / l**4) * (P*(1 + (1.049 - 0.0157*T) * P * 1e-6)/(1 + 0.003661*T)) - (0.0624 - 0.000680 / l**2) * RH / (1 + 0.003661*T)
n = R/1e6 + 1
return n
def Ciddor(l, CO2=450):
'''
From Ciddor, 1996
@@ -62,6 +63,7 @@ def Ciddor(l, CO2=450):
n = R/1e8 + 1
return n
def Edlen1953(l):
'''
From Edlen, 1953
@@ -84,6 +86,7 @@ def Edlen1953(l):
n = R/1e8 + 1
return n
def Edlen1966(l):
'''
From Edlen, 1966
@@ -106,7 +109,8 @@ def Edlen1966(l):
n = R/1e8 + 1
return n
def Owens(l, T=288.15, p=101325, H=0):
def Owens(l, T=288.15, p=101325, RH=0):
'''
From Owens, 1967
Equation 32
@@ -121,8 +125,8 @@ def Owens(l, T=288.15, p=101325, H=0):
Temperature in Kelvin
p : float
Atmospheric pressure in Pa
H : float
Humdity (0<=H<=1)
RH : float
Relative humdity (0<=H<=1)
Returns
-------
@@ -132,10 +136,11 @@ def Owens(l, T=288.15, p=101325, H=0):
P = hPA2mmHg(p/100)
T = K2C(T)
s = 1 / l
R = 8342.13 + 2406030 / (130 - s**2) + 15997 / (38.9 - s**2) * (P/720.775) * ((1 + P * (0.817 - 0.0133) * 1e-6)/(1 + 0.0036610*T)) - H * (5.722 - 0.0457*s**2)
R = 8342.13 + 2406030 / (130 - s**2) + 15997 / (38.9 - s**2) * (P/720.775) * ((1 + P * (0.817 - 0.0133) * 1e-6)/(1 + 0.0036610*T)) - RH * (5.722 - 0.0457*s**2)
n = R/1e8 + 1
return n
def BonschPotulski(l, T=288.15, p=101325, CO2=450):
'''
From Bonsch & Potulski, 1998
@@ -168,6 +173,7 @@ def BonschPotulski(l, T=288.15, p=101325, CO2=450):
n = Rtp + 1
return n
def BirchDowns(l):
'''
From Birch & Downs, 1993 and 1994 (correction)
@@ -190,6 +196,7 @@ def BirchDowns(l):
n = R/1e8 + 1
return n
def PeckReeder(l):
'''
From Peck & Reeder, 1972
@@ -213,8 +220,70 @@ def PeckReeder(l):
return n
def slalib(l, T=288.15, p=101325, H=0, h=0, lat=-24, tlr=0.0065, eps=1e-10):
def HohenkerkAndSinclair(l, T=288.15, p=101325, RH=0, h=0, lat=0):
'''
Calcalation of the refractive index following Hohenkerk & Sinclair
(1985), which is the same one as used in SLALIB.
This equation is based on the Barrell & Sears equation, but with
slightly different values. The refractive index values here seem
to be a bit higher than the original Barrel and Sears values.
Parameters
----------
l : float
Wavelength in microns
T : float
Temperature in Kelvin
p : float
Atmospheric pressure in Pa
RH : float
fractional humidity (0=<H=<1)
h : float
Altitude of the observer (default=0 m)
lat : float
Latitude of the observer (default=-24)
Returns
-------
n : float
Refractive index of atmospheric air at the given conditions
'''
# Some constants
alpha = 0.0065
delta = 18.36
R = 8314.36
Md = 28.966
Mw = 18.016
# Pressure in millibars
P0 = p/100
# Local acceleration due to gravity
g_local = 9.784 * (1 - 0.0026 * np.cos(2*np.deg2rad(lat))) - 0.00000028*h
gamma = g_local * Md / (R * alpha)
# Partial pressure of water vapour at observer
Pw = RH * (T/247.1)**18.36
# Refractivity * 1e6 at reference conditions
A = (287.604 + 1.6288*l**-2 + 0.0136*l**-4) * 273.15/1013.25
# A = (287.5522 + 1.6288*l**-2 + 0.0136*l**-4) * 273.15/1013.25
P = (P0 + (1 - Mw/Md) * gamma/(delta - gamma) * Pw )\
- (1 - Mw/Md) * gamma / (delta-gamma) * Pw
# Refractive index at given conditions
n = 1 + 1e-6 * (A * P - 11.2684*Pw)/T
return n
def slalib(l, T=288.15, p=101325, RH=0, h=0, lat=-24, tlr=0.0065, eps=1e-10):
'''
NOTE: This function still works for now, but is considered DEPRECATED.
Use BarrellAndSears() or HohenkerkAndSinclair() instead.
SLALIB uses the same atmospheric model as ZEMAX
based on the works of Hohenkerk & Sinclair and Seidelmann.
They take the B&S refraction formula as a basis.
@@ -228,8 +297,8 @@ def slalib(l, T=288.15, p=101325, H=0, h=0, lat=-24, tlr=0.0065, eps=1e-10):
Temperature in Kelvin
p : float
Atmospheric pressure in Pa
H : float
fractional humidity (0=<H=<1)
RH : float
Relative humidity (0=<H=<1)
h : float
Altitude of the observer (default=0 m)
lat : float
@@ -243,6 +312,14 @@ def slalib(l, T=288.15, p=101325, H=0, h=0, lat=-24, tlr=0.0065, eps=1e-10):
-------
n : float
Refractive index of atmospheric air at the given conditions
Notes
-----
1. I don't understand why this function works. It calculates the
refraction and somehow returns the refractive index. Perhaps
this is a very particular set of input parameters that make it
work. It does closely follow BarrellAndSears() for standard
conditions.
'''
try:
from pyslalib import slalib
@@ -256,14 +333,14 @@ def slalib(l, T=288.15, p=101325, H=0, h=0, lat=-24, tlr=0.0065, eps=1e-10):
if type(l) == float:
l = [l]
for wl in l:
R.append(slalib.sla_refro(zObs, h, T, p, H, wl, lat, tlr, eps))
R.append(slalib.sla_refro(zObs, h, T, p, RH, wl, lat, tlr, eps))
if len(l) == 1:
return R[0]+1
else:
return np.asarray(R)+1
def Mathar(l, T=288.15, p=101325, H=0):
def Mathar(l, T=288.15, p=101325, RH=0):
'''
Refractivity model by Mathar (2007), valid above 1.4 microns
Code taken from
@@ -392,7 +469,7 @@ def Mathar(l, T=288.15, p=101325, H=0):
s = 1e4/l # cm^-1
n = 1
H = H*100
H = RH*100
for j in range(0, 6):
n += ( cref[j] + cT[j]*(1/T-1/Tref) + cTT[j]*(1/T-1/Tref)**2
@@ -420,6 +497,7 @@ def K2C(K):
'''
return K - 273.15
def hPA2mmHg(hPa):
'''
hPa to mmHg conversion