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

+364
View File
@@ -0,0 +1,364 @@
#!/usr/bin/env Python3
from .ciddorModel import Observatory
from .refractionModels import refraction
from .dispersionModels import dispersion
from .neoslalib import sla_refro
'''
@ Author: Joost van den Born
@ Contact: born@astron.nl
@ Description: Some functions for quick testing.
'''
def quick_refractive_index(l, conditions='STANDARD', T=288.15, p=101325,
RH=0.0, xc=450, lat=0, h=0):
'''
Function to quickly calculate the refractive index
of atmospheric air at reference conditions, given
a wavelength l.
Parameters
----------
l : float
Wavelength in microns
conditions: string
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
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
Returns
-------
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
# Initializing dispersion model
at = Observatory()
# Calculating indices of refraction for l
n = at.n_tph(l=l, T=T, p=p, RH=RH, xc=xc)
return n
def quick_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
RH=0.0, xc=450, lat=0, h=0):
'''
Function to quickly calculate the refraction
of atmospheric air at reference conditions,
given a wavelength l.
Parameters
----------
l : float
Wavelength in microns
zenith : float
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.
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
Returns
-------
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
# Initializing dispersion model
at = Observatory()
# Calculating indices of refraction for l
n = at.n_tph(l=l, T=T, p=p, RH=RH, xc=xc)
# Density of the atmosphere (following CIPM-81/91 equations)
rho = at.rho(p=p, T=T, RH=RH, xc=xc)
# Initializing refraction model and setting the reduced height
ref = refraction(lat, h)
ref.setReducedHeight(p, rho)
return ref.cassini(n, zenith)
def quick_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15,
p=101325, RH=0.0, xc=450, lat=0, h=0):
'''
Function to quickly calculate the dispersion
of atmospheric air at reference conditions,
given a wavelength l.
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
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
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
Returns
-------
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
# Initializing dispersion model
at = Observatory()
# Calculating indices of refraction for l1 and l2
n1 = at.n_tph(l=l1, T=T, p=p, RH=RH, xc=xc)
n2 = at.n_tph(l=l2, T=T, p=p, RH=RH, xc=xc)
# Density of the atmosphere (following CIPM-81/91 equations)
rho = at.rho(p=p, T=T, RH=RH, xc=xc)
# Initializing refraction model and setting the reduced height
disp = dispersion(lat, h)
disp.setReducedHeight(p, rho)
return disp.cassini(n1, n2, zenith)
def slalib_refraction(l, zenith, conditions='STANDARD', T=288.15, p=101325,
RH=0.0, xc=450, lat=0, h=0, tlr=0.0065, eps=1e-8, use_pyslalib=False):
'''
Calculates the atmospheric refraction assuming the SLALIB
package. 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.
The pySLALIB FORTRAN has been ported, so pyslalib is not
needed, but can still be used. There are minor numerical
differences, likely due to precision or declaration issues.
Parameters
----------
l : float
Wavelength in microns
zenith : float
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.
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 (default=0)
h : float (optional)
Altitude of the observer in meters
tlr : float
Temperature lapse rate (default=0.0065)
eps : float
Precision at which the calculation is aborted (default=1e-10)
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).
Returns
-------
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
# Converting units to the units that sla_refro() requires.
_zenith = np.deg2rad(zenith) # From degrees to radians
_P = p / 100 # From Pa to mbar
_phi = np.deg2rad(lat) # From degrees to radians
R = []
if type(l) == float or type(l) == int:
l = [l]
if use_pyslalib:
try:
from pyslalib import slalib
except ImportError as e:
print('pySLALIB package not found! Try installing it first.')
for wl in l:
# If using original slalib (e.g. PySLALIB)
Refrac = slalib.sla_refro(_zenith, h, T, _P, RH, wl, phi, tlr, eps)
R.append(np.degrees(Refrac))
# If using internal slalib port
else:
for wl in l:
Refrac = sla_refro(_zenith, h, T, _P, RH, wl, phi, tlr, eps)
R.append(np.degrees(Refrac))
if len(l) == 1:
return R[0]
else:
return np.asarray(R)
def slalib_dispersion(l1, l2, zenith, conditions='STANDARD', T=288.15, p=101325,
RH=0.0, xc=450, lat=0, h=0, tlr=0.0065, eps=1e-8, use_pyslalib=False):
'''
Calculates the atmospheric refraction assuming the SLALIB
package. 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.
The pySLALIB FORTRAN has been ported, so pyslalib is not
needed, but can still be used. There are minor numerical
differences, likely due to precision or declaration issues.
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
'STANDARD' or 'CERRO_ARMAZONES', refers
to the standard atmospheric conditions.
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 (default=0)
h : float (optional)
Altitude of the observer in meters
tlr : float
Temperature lapse rate (default=0.0065)
eps : float
Precision at which the calculation is aborted (default=1e-10)
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).
Returns
-------
dR : float
Refraction in degrees
'''
R1 = slalib_refraction(l1, zenith, conditions, T, p, RH, xc,\
lat, h, tlr, eps, use_pyslalib)
R2 = slalib_refraction(l2, zenith, conditions, T, p, RH, xc,\
lat, h, tlr, eps, use_pyslalib)
dR = R1 - R2
return dR