131 lines
3.2 KiB
Python
131 lines
3.2 KiB
Python
import numpy as np
|
|
import warnings
|
|
from . import Const
|
|
|
|
def vectorize(x):
|
|
'''
|
|
Vectorize a number(int, float) or a list to a numpy array.
|
|
'''
|
|
try:
|
|
n = len(x)
|
|
x = np.array(x)
|
|
except:
|
|
x = np.array([x])
|
|
return x
|
|
|
|
def wraplon(lon):
|
|
'''
|
|
Wrap a longitude in range of [0,360] to [-180,180].
|
|
|
|
Usage:
|
|
lon_wrap = wraplon(lon)
|
|
|
|
Inputs:
|
|
lon -> [float] longitude in range of [0,360]
|
|
|
|
Outputs:
|
|
lon_wrap -> [float] wrapped longitude in range of [-180,180]
|
|
'''
|
|
if lon > 180:
|
|
lon_wrap = lon - 360
|
|
else:
|
|
lon_wrap = lon
|
|
return lon_wrap
|
|
|
|
def wraplons(lons):
|
|
'''
|
|
Wrap a set of longitudes in range of [0,360] to [-180,180].
|
|
|
|
Usage:
|
|
lons_wrap = wraplons(lons)
|
|
|
|
Inputs:
|
|
lons -> [float list/array] longitudes in range of [0,360]
|
|
|
|
Outputs:
|
|
lons_wrap -> [float array] wrapped longitudes in range of [-180,180]
|
|
'''
|
|
lons = vectorize(lons)
|
|
lons_wrap = lons.copy()
|
|
flags = lons > 180
|
|
lons_wrap[flags] = lons[flags] - 360
|
|
|
|
return lons_wrap
|
|
|
|
def hms_conver(h,m,s):
|
|
'''
|
|
Convert the form of hour/minute/second to hours and seconds.
|
|
|
|
Uasge:
|
|
hours,seconds = hms_conversion(h,m,s)
|
|
'''
|
|
hours = h + m/60 + s/3.6e3
|
|
seconds = h*3.6e3 + m*60 + s
|
|
return hours,seconds
|
|
|
|
def ydhms_days(ydhms):
|
|
'''
|
|
Convert the form of hour/minute/second to hours and seconds.
|
|
|
|
Uasge:
|
|
hours,seconds = hms_conversion(h,m,s)
|
|
'''
|
|
days = ydhms[1] + ydhms[2]/24 + ydhms[3]/1440 + ydhms[4]/86400 - 1
|
|
return days
|
|
|
|
def alt_conver(alts,alt_type='geometric'):
|
|
'''
|
|
Fulfill conversions between geometric altitudes and geopotential altitudes.
|
|
|
|
Usage:
|
|
zs,hs = alt_conver(alts,'geometric')
|
|
or
|
|
zs,hs = alt_conver(alts,'geopotential')
|
|
|
|
Inputs:
|
|
alts -> [float list/array] geometric altitudes or geopotential altitudes, [km]
|
|
|
|
Parameters:
|
|
alt_type -> [string] 'geometric' or 'geopotential'
|
|
|
|
Outputs:
|
|
zs -> [float array] geometric altitudes, [km]
|
|
hs -> [float array] geopotential altitudes, [km]
|
|
'''
|
|
|
|
alts = vectorize(alts)
|
|
|
|
R0 = Const.R0
|
|
|
|
if alt_type == 'geometric':
|
|
zs = alts
|
|
# from geometric altitude to geopotential altitude
|
|
hs = zs*R0/(R0+zs)
|
|
|
|
elif alt_type == 'geopotential':
|
|
hs = alts
|
|
# from geopotential altitude to geometric altitude
|
|
zs = hs*R0/(R0-hs)
|
|
return zs,hs
|
|
|
|
def check_altitude(zs,z_range,mode):
|
|
'''
|
|
Checks if altitudes are inside a valid range.
|
|
|
|
Inputs:
|
|
zs -> [float list/array] geometric altitude to be checked
|
|
lower_z -> [float] lower limit of geometric altitudes
|
|
upper_z -> [float] upper limit of geometric altitudes
|
|
'''
|
|
zs = np.array(zs)
|
|
|
|
lower_z,upper_z = z_range
|
|
# Assert in range
|
|
|
|
if (zs < lower_z).any() or (zs > upper_z).any():
|
|
msg_warning = "Geometric altitudes are outside the range of [{}, {}] km. Output values will be extrapolated for those heights.".format(lower_z,upper_z)
|
|
msg_error = "Geometric altitudes are outside the range of [{}, {}] km.".format(lower_z,upper_z)
|
|
if mode == 'warning':
|
|
warnings.warn(msg_warning)
|
|
elif mode == 'error':
|
|
raise Exception(msg_error) |