Added Filippenko model, updated B&S refractivity

This commit is contained in:
yosata committed 2020-09-07 21:20:09 +02:00
1 parent cce60766fc
commit 8f9a0bbbea
5 files changed
+268 -91

No files matched your search

+1
View File
@@ -8,3 +8,4 @@ from .refractionModels import *
from .misc import *
from .refractivityModels import *
from .neoslalib import *
from .observatories import *
+113 -82
View File
@@ -3,12 +3,93 @@ from .ciddorModel import Observatory
from .refractionModels import refraction
from .dispersionModels import dispersion
from .neoslalib import sla_refro
from .observatories import observatories
from .refractivityModels import Edlen1953
import numpy as np
'''
@ Author: Joost van den Born
@ Contact: born@astron.nl
@ Description: Some functions for quick testing.
'''
def get_conditions(location):
'''
Returns the mean conditions at various site. Currently
supported locations:
- 'STANDARD'
- 'CERRO_ARMAZONES'
- 'CERRO_PARANAL'
- 'LA_PALMA'
- 'LA_SILLA'
- 'LAS_CAMPANAS'
- 'MAUNA_KEA'
Parameters
----------
location : string
String denoting the desired location
Returns
-------
observatory : dict
Dictionary containing the atmospheric parameters
'''
observatory = observatories[location]
return observatory
def Filippenko1982(l1, l2, zenith, conditions='STANDARD', T=288.15, p=101325,
RH=0.0, xc=450, lat=0, h=0, f=None):
'''
Calculates the refraction following the 1982 paper by
Alexei V. Filippenko.
The refraction is based on a flat atmosphere and the refractivity
values are calculated from a modified Edlen (1953) equation.
Parameters
----------
l1 : float
Shortest wavelength of interest in micron.
l2 : float
Longest wavelength of interest in micron.
zenith : float
Angle of observation in degrees.
zenith = 0 means the observation is directly overhead.
conditions : string
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
Atmospheric pressure in Pa
RH : float (optional)
Relative humidity
xc : float (optional)
CO2 density in parts per million
lat : float (optional)
Latitude of the observer in degrees
h : float (optional)
Altitude of the observer in meters
f : float
Water vapour pressure (default=None). If None, it is
calculated automatically.
Returns
-------
R : float
Atmospheric refraction in degrees
'''
if conditions is not None:
T, p, RH, xc, lat, h, _ = get_conditions(conditions).values()
n1 = Edlen1953(l1, T=T, p=p, RH=RH, f=f)
n2 = Edlen1953(l2, T=T, p=p, RH=RH, f=f)
dR = (n1 - n2) * np.tan(np.deg2rad(zenith))
return np.degrees(dR)
def quick_refractive_index(l, conditions='STANDARD', T=288.15, p=101325,
@@ -23,8 +104,10 @@ def quick_refractive_index(l, conditions='STANDARD', T=288.15, p=101325,
l : float
Wavelength in microns
conditions: string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
@@ -43,23 +126,8 @@ def quick_refractive_index(l, conditions='STANDARD', T=288.15, p=101325,
n : float
Refractive index for the given conditions.
'''
if conditions == 'STANDARD':
# Parameters at Cerro Armazones
T = 288.15 # k
p = 101325 # Pa
RH = 0.0
xc = 450 # ppm
lat = 0 # degrees
h = 0 # m
elif conditions == 'CERRO_ARMAZONES':
# Parameters at Cerro Armazones
T = 279.65 # k
p = 71200 # Pa
RH = 0.22
xc = 450 # ppm
lat = -24.5983 # degrees
h = 3064 # m
if conditions is not None:
T, p, RH, xc, lat, h, _ = get_conditions(conditions).values()
# Initializing dispersion model
at = Observatory()
@@ -84,8 +152,10 @@ def quick_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
Angle of observation in degrees.
zenith = 0 means the observation is directly overhead.
conditions : string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
@@ -104,23 +174,8 @@ def quick_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
R : float
Refraction in degrees
'''
if conditions == 'STANDARD':
# Parameters at Cerro Armazones
T = 288.15 # k
p = 101325 # Pa
RH = 0.0
xc = 450 # ppm
lat = 0 # degrees
h = 0 # m
elif conditions == 'CERRO_ARMAZONES':
# Parameters at Cerro Armazones
T = 279.65 # k
p = 71200 # Pa
RH = 0.22
xc = 450 # ppm
lat = -24.5983 # degrees
h = 3064 # m
if conditions is not None:
T, p, RH, xc, lat, h, _ = get_conditions(conditions).values()
# Initializing dispersion model
at = Observatory()
@@ -154,8 +209,10 @@ def quick_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15,
Angle of observation in degrees.
zenith = 0 means the observation is directly overhead.
conditions : string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
@@ -174,23 +231,8 @@ def quick_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15,
dR : float
Atmospheric dispersion in degrees
'''
if conditions == 'STANDARD':
# Parameters at Cerro Armazones
T = 288.15 # k
p = 101325 # Pa
RH = 0.0
xc = 450 # ppm
lat = 0 # degrees
h = 0 # m
elif conditions == 'CERRO_ARMAZONES':
# Parameters at Cerro Armazones
T = 279.65 # k
p = 71200 # Pa
RH = 0.22
xc = 450 # ppm
lat = -24.5983 # degrees
h = 3064 # m
if conditions is not None:
T, p, RH, xc, lat, h, _ = get_conditions(conditions).values()
# Initializing dispersion model
at = Observatory()
@@ -228,8 +270,10 @@ def slalib_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
Angle of observation in degrees.
zenith = 0 means the observation is directly overhead.
conditions : string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
@@ -245,11 +289,11 @@ def slalib_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
tlr : float
Temperature lapse rate (default=0.0065)
eps : float
Precision at which the calculation is aborted (default=1e-10)
Precision at which the calculation is aborted (default=1e-8)
use_pyslalib : bool
Flag that indicates that the user wants to use the pySlalib
package. If False, the internal python port of the original
FORTRAN code will be used. (Default=False).
FORTRAN code will be used. (default=False).
Returns
-------
@@ -257,23 +301,8 @@ def slalib_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
Refraction in degrees
'''
if conditions == 'STANDARD':
# Parameters at Cerro Armazones
T = 288.15 # k
p = 101325 # Pa
RH = 0.0
xc = 450 # ppm
lat = 0 # degrees
h = 0 # m
elif conditions == 'CERRO_ARMAZONES':
# Parameters at Cerro Armazones
T = 279.65 # k
p = 71200 # Pa
RH = 0.22
xc = 450 # ppm
lat = -24.5983 # degrees
h = 3064 # m
if conditions is not None:
T, p, RH, xc, lat, h, _ = get_conditions(conditions).values()
# Converting units to the units that sla_refro() requires.
_zenith = np.deg2rad(zenith) # From degrees to radians
@@ -326,8 +355,10 @@ def slalib_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15, p=101325,
Angle of observation in degrees.
zenith = 0 means the observation is directly overhead.
conditions : string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
Refers to the standard conditions of the
observatory. See get_conditions() for more info.
If set to 'None', the conditions specified
after will be used.
T : float (optional)
Temperature in Kelvin
p : float (optional)
@@ -343,11 +374,11 @@ def slalib_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15, p=101325,
tlr : float
Temperature lapse rate (default=0.0065)
eps : float
Precision at which the calculation is aborted (default=1e-10)
Precision at which the calculation is aborted (default=1e-8)
use_pyslalib : bool
Flag that indicates that the user wants to use the pySlalib
package. If False, the internal python port of the original
FORTRAN code will be used. (Default=False).
FORTRAN code will be used. (default=False).
Returns
-------
+85
View File
@@ -0,0 +1,85 @@
observatories = {
'STANDARD': {
'T': 288.15,
'p': 101325,
'RH': 0.0,
'xc': 450,
'latitude': 0,
'altitude': 0,
'comment': 'Standard atmospheric conditions'
},
'CERRO_ARMAZONES': {
'T': 279.65,
'p': 71200,
'RH': 0.22,
'xc': 450,
'latitude': -24.5983,
'altitude': 3064,
'comment': 'Default conditions for Cerro Armazones, site of the ELT.\nValues are taken from the optical model of MICADO.'
},
'CERRO_PARANAL': {
'T': 285.95,
'p': 74300,
'RH': 0.15,
'xc': 450,
'latitude': -24.6230,
'altitude': 2635,
'comment': 'Average conditions at Cerro Paranal, site of the VLT.\nValues are taken from https://www.eso.org/sci/facilities/paranal/astroclimate/site.html and https://academic.oup.com/mnras/article/399/2/783/1061377'
},
'LA_SILLA': {
'T': 284.65,
'p': 77220,
'RH': 0.44,
'xc': 450,
'latitude': -29.25,
'altitude': 2400,
'comment': 'Average conditions of the La Silla Observatory.\nValues based on https://www.eso.org/gen-fac/pubs/astclim/lasilla/diffrefr.html'
},
'LAS_CAMPANAS': {
'T': 285.85,
'p': 76400,
'RH': 0.0,
'xc': 450,
'latitude': -29.016,
'altitude': 2380,
'comment': 'Mean conditions at Las Campanas observatory, site of the GMT.\nValues based on https://www.gmto.org/Resources/GMT-ID-01466-Chapter_5_Site_Evaluation.pdf and http://weather.lco.cl/'
},
'LA_PALMA': {
'T': 281.95,
'p': 77500,
'RH': 0.36,
'xc': 450,
'latitude': 28.764,
'altitude': 2396,
'comment': 'Average conditions for Roque de los Muchachos Observatory on La Palma, Spain.\nValues taken from https://academic.oup.com/mnras/article/399/2/783/1061377'
},
'MAUNA_KEA': {
'T': 274.45,
'p': 61400,
'RH': 0.48,
'xc': 450,
'latitude': 19.826,
'altitude': 4205,
'comment': 'Average conditions at the Mauna Kea Observatory.\nValues taken from http://www.soest.hawaii.edu/MET/Faculty/businger/mauna_kea/daSilvaThesisFinal.pdf, Ch. 3. and https://www.eso.org/gen-fac/pubs/astclim/espas/espas_reports/ESPAS-MaunaKea.pdf'
}
# 'MT_GRAHAM': {
# 'T': 278.15,
# 'p': 68500,
# 'RH': 0.0,
# 'xc': 450,
# 'latitude': 32.701,
# 'altitude': 3191,
# 'comment': 'Mean conditions at Mount Graham International Observatory,\
# site of the LBT. Values are estimates.'
# },
# 'FRED_LAWRENCE_WHIPPLE': {
# 'T': 288.15,
# 'p': 74300,
# 'RH': 0.0,
# 'xc': 450,
# 'latitude': 31.681,
# 'altitude': 2616,
# 'comment': 'Mean conditions at Fred Lawrence Whipple Observatory, site of\
# the MMT. Values are estimates.'
# }
}
+52 -5
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, RH=0):
def BarrellAndSears(l, T=288.15, p=101325, RH=0, f=None):
'''
From Barrell & Sears, 1939
Equation 7.7, page 52
@@ -26,15 +26,20 @@ def BarrellAndSears(l, T=288.15, p=101325, RH=0):
Atmospheric pressure in Pascal
RH : float
Relative humidity (0=<H=<1)
f : float
Water vapour pressure in Pascal
Returns
-------
n : float
Refractive index of atmospheric air at the given conditions
'''
if f is None:
f = RH * svp(T)
f_mmHg = hPA2mmHg(f/100)
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) * RH / (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) * f_mmHg / (1 + 0.003661*T)
n = R/1e6 + 1
return n
@@ -64,17 +69,25 @@ def Ciddor(l, CO2=450):
return n
def Edlen1953(l):
def Edlen1953(l, T=288.15, p=101325, RH=0, f=None):
'''
From Edlen, 1953
Equation 2
At standard conditions only
At standard conditions only.
Following Filippenko (1982), eqs. 2 & 3 we also include
the modification proposed by Barrell in 1951.
Parameters
----------
l : float
Wavelength in microns
T : float
Temperature in Kelvin
p : float
Atmospheric pressure in Pascal
f : float
Water vapor pressure in Pascal
Returns
-------
@@ -83,7 +96,20 @@ def Edlen1953(l):
'''
s = 1 / l
R = 6432.8 + 2949810 / (146 - s**2) + 25540/(41-s**2)
n = R/1e8 + 1
n_standard = R/1e8 + 1
pHg = hPA2mmHg(p/100)
Tc = K2C(T)
if f is None:
f = RH * svp(T)
f_mmHg = hPA2mmHg(f/100)
# Changes in temperature and pressure, from Barrell (1951)
n_tp = R/1e8 * (pHg * (1 + (1.049 - 0.0157*Tc) * 1e-6 * pHg ) ) / ( 720.883 * (1 + 0.003661 * Tc)) + 1
# Correction for water vapour pressure
n_svp = (n_tp - 1) * 1e6 - ( 0.0624 - 0.000680 * s**2 ) / (1 + 0.003661 * Tc) * f_mmHg
n = n_svp/1e6 + 1
return n
@@ -481,6 +507,7 @@ def Mathar(l, T=288.15, p=101325, RH=0):
return n
# Other necessary conversion or calculations
def K2C(K):
'''
Kelvin to Celsius conversion
@@ -514,3 +541,23 @@ def hPA2mmHg(hPa):
'''
return 0.7500616827 * hPa
def svp(T):
'''
Saturation vapour pressure in Pa.
Parameters
----------
T : float
Atmospheric temperature in Kelvin
Returns
-------
svp : float
Saturation vapour pressure in Pa
'''
_A = 1.2378847e-5 # K^-2
_B = -1.9121316e-2 # K^-2
_C = 33.93711047
_D = -6.3431645e3 # K^-2
return np.exp(_A*T**2 + _B*T + _C + _D/T)