# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
from astropy import units as u
from itur.models.itu1144 import (bilinear_2D_interpolator,
bicubic_2D_interpolator)
from itur.utils import (prepare_input_array, prepare_output_array,
load_data_interpolator, get_input_type)
class __ITU1510__():
"""Annual mean surface temperature
Available versions include:
* P.1510-0 (02/01) (Current version)
"""
# This is an abstract class that contains an instance to a version of the
# ITU-R P.1510 recommendation.
def __init__(self, version=1):
if version == 1:
self.instance = _ITU1510_1_()
elif version == 0:
self.instance = _ITU1510_0_()
else:
raise ValueError('Version ' + str(version) + ' is not implemented'
' for the ITU-R P.1510 model.')
@property
def __version__(self):
return self.instance.__version__
def surface_mean_temperature(self, lat, lon):
"""
Method to compute the annual mean surface temperature (K).
The temperature is computed at 2 m above the surface of the Earth.
"""
return self.instance.temperature(lat, lon)
def surface_month_mean_temperature(self, lat, lon, m):
# Abstract method to compute the monthly surface mean temperature
fcn = np.vectorize(self.instance.surface_month_mean_temperature,
excluded=[0, 1], otypes=[np.ndarray])
return np.array(fcn(lat, lon, m).tolist())
class _ITU1510_1_():
def __init__(self):
self.__version__ = 1
self.year = 2017
self.month = 6
self.link = 'https://www.itu.int/rec/R-REC-P.1510/' +\
'recommendation.asp?lang=en&parent=R-REC-P.1510-1-201706-I'
self.__months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
self._temperature = {}
self._month_temperature = {}
def temperature(self, lat, lon):
if not self._temperature:
self._temperature = load_data_interpolator(
'1510/v1_lat.npz', '1510/v1_lon.npz',
'1510/v1_t_annual.npz', bilinear_2D_interpolator)
lon[lon > 180] = lon[lon > 180] - 360
return self._temperature(
np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def month_temperature(self, lat, lon, m):
if not self._month_temperature:
for _m in self.__months:
self._month_temperature[_m] = load_data_interpolator(
"1510/v1_lat.npz",
"1510/v1_lon.npz",
f"1510/v1_t_month{_m:02d}.npz",
bilinear_2D_interpolator,
)
lon[lon > 180] = lon[lon > 180] - 360
return self._month_temperature[m](
np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def surface_mean_temperature(self, lat, lon):
"""
Method to compute the annual mean surface temperature (K) at 2 m
above the surface of the Earth
"""
return self.temperature(lat, lon)
def surface_month_mean_temperature(self, lat, lon, m):
return self.month_temperature(lat, lon, m)
class _ITU1510_0_():
def __init__(self):
self.__version__ = 0
self.year = 2001
self.month = 2
self.link = 'https://www.itu.int/rec/R-REC-P.1510/' +\
'recommendation.asp?lang=en&parent=R-REC-P.1510-0-200102-I'
self._temperature = {}
def temperature(self, lat, lon):
if not self._temperature:
self._temperature = load_data_interpolator(
'1510/v0_lat.npz', '1510/v0_lon.npz',
'1510/v0_temp.npz', bicubic_2D_interpolator)
return self._temperature(
np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def surface_month_mean_temperature(self, lat, lon, m):
raise NotImplementedError(
f"The monthly mean temperature is notimplemented in recomendation ITU-R P.1510-{self.__version__}"
)
__model = __ITU1510__()
[docs]def change_version(new_version):
"""
Change the version of the ITU-R P.1510 recommendation currently being used.
This function changes the model used for the ITU-R P.1510 recommendation
to a different version.
Parameters
----------
new_version : int
Number of the version to use.
Valid values are:
* 1: Activates recommendation ITU-R P.1510-1 (06/17) (Current version)
* 0: Activates recommendation ITU-R P.1510-0 (02/01) (Current version)
"""
global __model
__model = __ITU1510__(new_version)
[docs]def get_version():
"""
Obtain the version of the ITU-R P.1510 recommendation currently being used.
Returns
-------
version: int
Version currently being used.
"""
return __model.__version__
[docs]def surface_mean_temperature(lat, lon):
"""
Annual mean surface temperature (K) at 2 m above the surface of the Earth.
A method to estimate the annual mean surface temperature (K) at 2 m
above the surface of the Earth
Parameters
----------
lat : number, sequence, or numpy.ndarray
Latitudes of the receiver points
lon : number, sequence, or numpy.ndarray
Longitudes of the receiver points
Returns
-------
annual_temperature: numpy.ndarray
Annual mean surface temperature (K). Same dimensions as lat and lon.
References
----------
[1] Annual mean surface temperature:
https://www.itu.int/rec/R-REC-P.1510/en
"""
type_output = get_input_type(lat)
lat = prepare_input_array(lat)
lon = prepare_input_array(lon)
lon = np.mod(lon, 360)
val = __model.surface_mean_temperature(lat, lon)
return prepare_output_array(val, type_output) * u.Kelvin
[docs]def surface_month_mean_temperature(lat, lon, m):
"""
Monthly mean surface temperature (K) at 2 m above the surface of the Earth.
A method to estimate the monthly mean surface temperature (K) at 2 m
above the surface of the Earth
Parameters
----------
lat : number, sequence, or numpy.ndarray
Latitudes of the receiver points
lon : number, sequence, or numpy.ndarray
Longitudes of the receiver points
m : integer
Index of the month (1=Jan, 2=Feb, 3=Mar, 4=Apr, ...)
Returns
-------
monthly_temperature: numpy.ndarray
Monthly mean surface temperature (K). Same dimensions as lat and lon.
References
----------
[1] Annual mean surface temperature:
https://www.itu.int/rec/R-REC-P.1510/en
"""
type_output = get_input_type(lat)
lat = prepare_input_array(lat)
lon = prepare_input_array(lon)
lon = np.mod(lon, 360)
val = __model.surface_month_mean_temperature(lat, lon, m)
return prepare_output_array(val, type_output) * u.Kelvin