From 2a6457a4d104a900a1cf7e19055f094ed499e8e3 Mon Sep 17 00:00:00 2001 From: whitetuft Date: Thu, 2 Nov 2023 19:52:55 +0100 Subject: [PATCH 1/9] [doc] fix typo --- pyrtlib/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrtlib/utils.py b/pyrtlib/utils.py index 56e37f46..21bdd684 100644 --- a/pyrtlib/utils.py +++ b/pyrtlib/utils.py @@ -235,7 +235,7 @@ def mr2rh(p: np.ndarray, t: np.ndarray, w: np.ndarray, Tconvert: np.ndarray = None) -> np.ndarray: - """Determine relative humidity (rh) givenvreference pressure (mbar), temperature (K), and + """Determine relative humidity (rh) given reference pressure (mbar), temperature (K), and water vapor mass mixing ratio (g/kg) Two RHs are returned: rh1 is with RH defined as the ratio of water vapor partial pressure From 95dda7aad35bce56973f74a898d88102a49dc87a Mon Sep 17 00:00:00 2001 From: whitetuft Date: Mon, 6 Nov 2023 10:14:10 +0100 Subject: [PATCH 2/9] add unit test for absmodel --- pyrtlib/tests/test_absorption_model.py | 48 ++++++++++++++++++++++++++ pyrtlib/utils.py | 7 ++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 pyrtlib/tests/test_absorption_model.py diff --git a/pyrtlib/tests/test_absorption_model.py b/pyrtlib/tests/test_absorption_model.py new file mode 100644 index 00000000..a6c10c3e --- /dev/null +++ b/pyrtlib/tests/test_absorption_model.py @@ -0,0 +1,48 @@ +import os +# from pathlib import Path +from unittest import TestCase +from pyrtlib.absorption_model import (H2OAbsModel, O2AbsModel, + N2AbsModel, LiqAbsModel) + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class Test(TestCase): + def test_setter_model(self): + h2o = H2OAbsModel() + h2o.model = 'R22SD' + assert 'R22' != h2o.model + + o2 = O2AbsModel() + o2.model = 'R22' + assert 'R20' != o2.model + + def test_lineshape(self): + H2OAbsModel.model = 'R22SD' + H2OAbsModel.set_ll() + assert H2OAbsModel.h2oll.reftline == 296. + + H2OAbsModel.model = 'R98' + H2OAbsModel.set_ll() + assert H2OAbsModel.h2oll.reftline != 296. + + if hasattr(H2OAbsModel, 'model'): + assert H2OAbsModel.model != 'PIPPO' + + def test_absn2(self): + N2AbsModel.model = 'R22SD' + absn2 = N2AbsModel.n2_absorption(267., 800., 55.0034) + assert absn2 == 0.000278315910216229 + + N2AbsModel.model = 'R98' + absn2 = N2AbsModel.n2_absorption(267., 800., 55.0034) + assert absn2 != 0.000278315910216229 + + def test_absliq(self): + LiqAbsModel.model = 'R22SD' + absliq = LiqAbsModel.liquid_water_absorption(0.05, 183.0034, 270.) + assert absliq == 0.09822164244021624 + + LiqAbsModel.model = 'R98' + absliq = LiqAbsModel.liquid_water_absorption(0.05, 183.0034, 270.) + assert absliq != 0.09822164244021624 diff --git a/pyrtlib/utils.py b/pyrtlib/utils.py index 21bdd684..0f076239 100644 --- a/pyrtlib/utils.py +++ b/pyrtlib/utils.py @@ -6,13 +6,14 @@ __date__ = 'March 2021' __copyright__ = '(C) 2021, CNR-IMAA' -from typing import Tuple, Optional, Union, List, Dict +import types +from typing import Tuple, Optional, Union, List import sys from importlib import reload import numpy as np -def import_lineshape(name: str) -> Dict: +def import_lineshape(name: str) -> types.ModuleType: """Import a named object from a module in the context of this function. Used to import line list for absorption models. @@ -22,7 +23,7 @@ def import_lineshape(name: str) -> Dict: name (str): Absorption model name. Returns: - Dict: Dictionary of line list of the absorption model chose. + types.ModuleType: Dictionary of line list of the absorption model chose. See also: :py:func:`~pyrtlib.absorption_model.H2OAbsModel.set_ll` From 9b2c1c3bd4e95127d45da7d3782bc08a2f44cdfa Mon Sep 17 00:00:00 2001 From: whitetuft Date: Fri, 3 Nov 2023 07:36:54 +0100 Subject: [PATCH 3/9] [doc] fix reference --- pyrtlib/tb_spectrum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrtlib/tb_spectrum.py b/pyrtlib/tb_spectrum.py index c19f7e52..6f575ca3 100644 --- a/pyrtlib/tb_spectrum.py +++ b/pyrtlib/tb_spectrum.py @@ -36,7 +36,7 @@ def __init__(self, z: np.ndarray, p: np.ndarray, t: np.ndarray, rh: np.ndarray, profiles are not modified within this subroutine. It is assumed that the input profiles start at the antenna height (zX(1)). The input profiles must reach 50.0 mb. This subroutine uses the - algorithms described in Schroeder and Westwater (1991). + algorithms described in [Schroeder-Westwater-1991]_. Args: z (np.ndarray): Height profile (km). From 5a8ed145548d46b251f00ecc0410d4988bd03f16 Mon Sep 17 00:00:00 2001 From: whitetuft Date: Fri, 3 Nov 2023 07:38:42 +0100 Subject: [PATCH 4/9] [doc] add reference --- docs/source/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/api.rst b/docs/source/api.rst index fc25928a..aa825fb2 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -6,7 +6,7 @@ Main class ========== The main class which computes brightness temperatures (Tb), mean radiating temperature (Tmr), and integrated absorption (Tau) for -clear or cloudy conditions. Also returns all integrated quantities that the original TBMODEL, Cyber Version, returned. +clear or cloudy conditions. Also returns all integrated quantities that the original TBMODEL, Cyber Version, returned ([Schroeder-Westwater-1991]_). .. autosummary:: :toctree: generated/ From c0510cd948a52e57e3af75e3e7fb723d1cf3cb16 Mon Sep 17 00:00:00 2001 From: whitetuft Date: Fri, 3 Nov 2023 18:00:41 +0100 Subject: [PATCH 5/9] minor fixes --- pyrtlib/tb_spectrum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrtlib/tb_spectrum.py b/pyrtlib/tb_spectrum.py index 6f575ca3..16c92950 100644 --- a/pyrtlib/tb_spectrum.py +++ b/pyrtlib/tb_spectrum.py @@ -78,7 +78,7 @@ def __init__(self, z: np.ndarray, p: np.ndarray, t: np.ndarray, rh: np.ndarray, raise SystemExit("ERROR: input profile seems incorrect. " "It must be monotonically increasing or decreasing") - if len(self.p) < 25 or min(self.p) > 10: + if len(self.p) < 25 or min(self.p) >= 10: warnings.warn(f"Number of levels too low ({len(self.p)}) or " f"minimum pressure value lower than 10 hPa ({min(self.p)}). " "Please considering profile extrapolation. Levels number must be higher than 25 " From fbf9dc612e8e2d6493dd15846f434055dc07a476 Mon Sep 17 00:00:00 2001 From: whitetuft Date: Sat, 4 Nov 2023 13:02:43 +0100 Subject: [PATCH 6/9] minor fix for O3 absmodel --- pyrtlib/absorption_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrtlib/absorption_model.py b/pyrtlib/absorption_model.py index 9fcdbfa5..f6d7c59e 100644 --- a/pyrtlib/absorption_model.py +++ b/pyrtlib/absorption_model.py @@ -747,7 +747,7 @@ def o3_absorption(self, t: np.ndarray, p: np.ndarray, f: np.ndarray, o3n: np.nda # add resonances within 1 ghz of f. most of the ozone is in the # stratosphere, so lines are relatively narrow, and lorentz shape # factor is ok. - if O3AbsModel.model in ["R22", "R222sd"]: + if O3AbsModel.model in ["R22", "R22SD"]: summ = 0.0 nlines = len(self.o3ll.fl) for k in range(0, nlines): From cb56267b274c4b8bbbde7193103c17de9eb73c4c Mon Sep 17 00:00:00 2001 From: whitetuft Date: Sat, 4 Nov 2023 19:40:45 +0100 Subject: [PATCH 7/9] [doc] fix docstring --- pyrtlib/utils.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pyrtlib/utils.py b/pyrtlib/utils.py index 0f076239..9ffebcf6 100644 --- a/pyrtlib/utils.py +++ b/pyrtlib/utils.py @@ -235,7 +235,7 @@ def ppmv2gkg(ppmv: np.ndarray, gasid: int) -> np.ndarray: def mr2rh(p: np.ndarray, t: np.ndarray, w: np.ndarray, - Tconvert: np.ndarray = None) -> np.ndarray: + Tconvert: np.ndarray = None) -> Tuple(np.ndarray, np.ndarray): """Determine relative humidity (rh) given reference pressure (mbar), temperature (K), and water vapor mass mixing ratio (g/kg) @@ -254,8 +254,8 @@ def mr2rh(p: np.ndarray, water pressure is calculated over ice instead of liquid water. Defaults to None. Returns: - numpy.ndarray: Relative humidity using ratios of gas pressures - numpy.ndarray: Relative humidity using WMO definition + numpy.ndarray: Relative humidity using ratios of gas pressures (%) + numpy.ndarray: Relative humidity using WMO definition (%) """ # saturation pressure esat = satvap(t) @@ -324,7 +324,7 @@ def mr2e(p: np.ndarray, mr: np.ndarray) -> np.ndarray: return e -def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: +def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> Tuple(np.ndarray, np.ndarray): """Convert water vapor density to relative humidity. Args: @@ -333,14 +333,15 @@ def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: p (np.ndarray): Pressure (mb). Returns: - np.ndarray: Relative humidity (fraction) + numpy.ndarray: Relative humidity using ratios of gas pressures (%) + numpy.ndarray: Relative humidity using WMO definition (%) """ e = (rho * t)/216.7 mr = e2mr(p, e) - rh = mr2rh(p, t, mr) + rh1, rh2 = mr2rh(p, t, mr) - return rh + return rh1, rh2 def rho2mr(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: From 3dd727bf054c3d6388868f1fda622a7893279f0f Mon Sep 17 00:00:00 2001 From: whitetuft Date: Sun, 5 Nov 2023 07:51:09 +0100 Subject: [PATCH 8/9] [doc] docstring update --- pyrtlib/utils.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pyrtlib/utils.py b/pyrtlib/utils.py index 9ffebcf6..2abfe798 100644 --- a/pyrtlib/utils.py +++ b/pyrtlib/utils.py @@ -235,7 +235,7 @@ def ppmv2gkg(ppmv: np.ndarray, gasid: int) -> np.ndarray: def mr2rh(p: np.ndarray, t: np.ndarray, w: np.ndarray, - Tconvert: np.ndarray = None) -> Tuple(np.ndarray, np.ndarray): + Tconvert: np.ndarray = None) -> Tuple[np.ndarray, np.ndarray]: """Determine relative humidity (rh) given reference pressure (mbar), temperature (K), and water vapor mass mixing ratio (g/kg) @@ -275,7 +275,7 @@ def mr2rh(p: np.ndarray, def mr2rho(mr: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: - """Determine water vapor density (g/m3) given reference pressure (mbar), temperature (K), and + """Determine water vapor density (:math:`g/m^3`) given reference pressure (mbar), temperature (K), and water vapor mass mixing ratio (g/kg) Equations were provided by Holger Linne' from Max Planck Institute. @@ -286,7 +286,7 @@ def mr2rho(mr: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: p (numpy.ndarray): Pressure profiles (mb). Returns: - numpy.ndarray: Water Vapor Density (g/m3) + numpy.ndarray: Water Vapor Density (:math:`g/m^3`) """ rho = np.multiply(np.multiply(mr, p), 0.3477) / t @@ -304,8 +304,8 @@ def mr2rho(mr: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: def mr2e(p: np.ndarray, mr: np.ndarray) -> np.ndarray: - """Compute H2O partial pressure (mbar) given pressure (mbar) - and H2O mass mixing ratio (g/kg) + """Compute :math:`H_2O` partial pressure (mbar) given pressure (mbar) + and :math:`H_2O` mass mixing ratio (g/kg) DCT 3/6/00 @@ -314,7 +314,7 @@ def mr2e(p: np.ndarray, mr: np.ndarray) -> np.ndarray: mr (numpy.ndarray): Mixing Ratio (g/kg). Returns: - numpy.ndarray: H2O partial pressure (mb). + numpy.ndarray: :math:`H_2O` partial pressure (mb). """ # ratio of water mass to dry air mass @@ -324,11 +324,11 @@ def mr2e(p: np.ndarray, mr: np.ndarray) -> np.ndarray: return e -def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> Tuple(np.ndarray, np.ndarray): +def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: """Convert water vapor density to relative humidity. Args: - rho (np.ndarray): Water vapor density (g/m3) + rho (np.ndarray): Water vapor density (:math:`g/m^3`) t (np.ndarray): Temperature (K) p (np.ndarray): Pressure (mb). @@ -346,10 +346,10 @@ def rho2rh(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> Tuple(np.ndarray, def rho2mr(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: """Determine water vapor mass mixing ratio (g/kg) given reference pressure (mbar), - temperature (t,K), and water vapor density (g/m3). + temperature (t,K), and water vapor density (:math:`g/m^3`). Args: - rho (np.ndarray): Water vapor density (g/m3) + rho (np.ndarray): Water vapor density (:math:`g/m^3`) t (np.ndarray): Temperature (K) p (np.ndarray): Pressure (mb). @@ -367,15 +367,15 @@ def rho2mr(rho: np.ndarray, t: np.ndarray, p: np.ndarray) -> np.ndarray: def e2mr(p: np.ndarray, e: np.ndarray) -> np.ndarray: - """Compute H2O mass mixing ratio (g/kg) given pressure (mbar) - and H2O partial pressure (mbar) + """Compute :math:`H_2O` mass mixing ratio (g/kg) given pressure (mbar) + and :math:`H_2O` partial pressure (mbar) Args: p (numpy.ndarray): Pressure (mb). - e (numpy.ndarray): H2O partial pressure (mb). + e (numpy.ndarray): :math:`H_2O` partial pressure (mb). Returns: - numpy.ndarray: H2O Mass Mixing Ratio (g/kg) + numpy.ndarray: :math:`H_2O` Mass Mixing Ratio (g/kg) """ # ratio of water mass to dry air mass @@ -822,10 +822,10 @@ def dewpoint2rh(td: float, def kgkg_to_kgm3(q: np.ndarray, p: np.ndarray, t: np.ndarray) -> np.ndarray: - r"""Utils function to convert from Kg Kg-1 to kg m-3. [Jacobson]_ + r"""Utils function to convert from :math:`kg/kg` to :math:`kg/m^3`. [Jacobson]_ - NWP models provide cloud liquid and ice water content in units kq kq-1. To convert - to g m-3 multiply the result of this function to the value in kg kg-1. + NWP models provide cloud liquid and ice water content in units :math:`kg/kg`. To convert + to :math:`g/m^3` multiply the result of this function to the value in :math:`kg/kg`. .. math:: LWC = q_{liq} \frac{10^2 P}{R_{moist} T} @@ -844,7 +844,7 @@ def kgkg_to_kgm3(q: np.ndarray, p: np.ndarray, t: np.ndarray) -> np.ndarray: The same equations are used for ice clouds, by replacing LWC by IWC and :math:`q_{liq}` by :math:`q_{ice}` Args: - q (numpy.ndarray): specific humidity (Kg Kg-1) + q (numpy.ndarray): specific humidity (:math:`kg/kg`) p (numpy.ndarray): pressure (hPa) t (numpy.ndarray): temperature (K) @@ -852,7 +852,7 @@ def kgkg_to_kgm3(q: np.ndarray, p: np.ndarray, t: np.ndarray) -> np.ndarray: numpy.ndarray: [description] References: - .. [1] M. Z. Jacobson. Fundamentals of atmospheric modelling. Cambridge Eds., 2005. + .. [1] M.Z., Jacobson. Fundamentals of atmospheric modelling. Cambridge Eds., 2005. """ eps = 0.621970585 @@ -864,7 +864,7 @@ def kgkg_to_kgm3(q: np.ndarray, p: np.ndarray, t: np.ndarray) -> np.ndarray: def ppmv_to_moleculesm3(mr: np.ndarray, p: np.ndarray, t: np.ndarray) -> np.ndarray: - """For any gas, this function converts mixing ratio (in ppmv) to number density (molecules/m3). + """For any gas, this function converts mixing ratio (in ppmv) to number density (:math:`molecules/m^3`). Args: mr (numpy.ndarray): mixing ratio in ppmv From d7138cf4541e791a02c12dfd08508e906bf9e784 Mon Sep 17 00:00:00 2001 From: whitetuft Date: Mon, 6 Nov 2023 17:55:39 +0100 Subject: [PATCH 9/9] add missing rosen model --- pyrtlib/absorption_model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyrtlib/absorption_model.py b/pyrtlib/absorption_model.py index f6d7c59e..392ccf84 100644 --- a/pyrtlib/absorption_model.py +++ b/pyrtlib/absorption_model.py @@ -67,6 +67,7 @@ def implemented_models() -> List[str]: 'R03', 'R16', 'R17', + 'R18', 'R19', 'R19SD', 'R20', @@ -78,6 +79,7 @@ def implemented_models() -> List[str]: 'R03', 'R16', 'R17', + 'R18', 'R19', 'R19SD', 'R20',