Skip to content

Commit

Permalink
Picciotto et al. 1960 isotopic temperature inference and [hydro]meteo…
Browse files Browse the repository at this point in the history
…ric water line formulae (journal club paper); fixes in bibliography checks; code cleanups (#1498)

Co-authored-by: Agnieszka Żaba <[email protected]>
Co-authored-by: AgnieszkaZaba <[email protected]>
  • Loading branch information
3 people authored Jan 14, 2025
1 parent 0219928 commit 86ddb1d
Show file tree
Hide file tree
Showing 22 changed files with 238 additions and 40 deletions.
6 changes: 4 additions & 2 deletions PySDM/formulae.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def __init__( # pylint: disable=too-many-locals
heterogeneous_ice_nucleation_rate: str = "Null",
fragmentation_function: str = "AlwaysN",
isotope_equilibrium_fractionation_factors: str = "Null",
isotope_meteoric_water_line_excess: str = "Null",
isotope_meteoric_water_line: str = "Null",
isotope_ratio_evolution: str = "Null",
isotope_diffusivity_ratios: str = "Null",
isotope_relaxation_timescale: str = "Null",
isotope_temperature_inference: str = "Null",
optical_albedo: str = "Null",
optical_depth: str = "Null",
particle_shape_and_density: str = "LiquidSpheres",
Expand Down Expand Up @@ -80,10 +81,11 @@ def __init__( # pylint: disable=too-many-locals
self.isotope_equilibrium_fractionation_factors = (
isotope_equilibrium_fractionation_factors
)
self.isotope_meteoric_water_line_excess = isotope_meteoric_water_line_excess
self.isotope_meteoric_water_line = isotope_meteoric_water_line
self.isotope_ratio_evolution = isotope_ratio_evolution
self.isotope_diffusivity_ratios = isotope_diffusivity_ratios
self.isotope_relaxation_timescale = isotope_relaxation_timescale
self.isotope_temperature_inference = isotope_temperature_inference
self.particle_shape_and_density = particle_shape_and_density
self.air_dynamic_viscosity = air_dynamic_viscosity
self.terminal_velocity = terminal_velocity
Expand Down
3 changes: 2 additions & 1 deletion PySDM/physics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
hygroscopicity,
impl,
isotope_equilibrium_fractionation_factors,
isotope_meteoric_water_line_excess,
isotope_meteoric_water_line,
isotope_ratio_evolution,
isotope_diffusivity_ratios,
isotope_relaxation_timescale,
isotope_temperature_inference,
latent_heat,
optical_albedo,
optical_depth,
Expand Down
19 changes: 19 additions & 0 deletions PySDM/physics/constants_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,22 @@ def compute_derived_values(c: dict):
isotopologue; in the paper timescale is calculated for tritium with assumption of no tritium
in the environment around the drop (Table 1).
"""

PICCIOTTO_18O_A = -0.9 * PER_MILLE / si.K
""" linear fit coefficients from [Picciotto et al. 1960](https://doi.org/10.1038/187857a0)
for atmospheric temperature inference from water isotopic composition
(note that the sign of A coefficient is opposite to match the paper plot - typo in the paper?) """
PICCIOTTO_18O_B = 6.4 * PER_MILLE
"""〃"""
PICCIOTTO_2H_A = -0.8 * PER_CENT / si.K
"""〃"""
PICCIOTTO_2H_B = 8 * PER_CENT
"""〃"""

PICCIOTTO_18O_TO_2H_SLOPE_COEFF = 0.8 * PER_CENT / PER_MILLE
""" [hydro]meteoric water line [Picciotto et al. 1960](https://doi.org/10.1038/187857a0) coeffs
(note that the delta-2H and delta-18O are swapped to match the paper plot - typo in the paper?)
(note that the sign of INTERCEPT is opposite to match the paper plot - typo in the paper?)
"""
PICCIOTTO_18O_TO_2H_INTERCEPT_COEFF = -1.8 * PER_CENT
"""〃"""
7 changes: 7 additions & 0 deletions PySDM/physics/isotope_meteoric_water_line/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
""" definitions of meteoric water line parameters
and definitions of the excess quantities"""

from PySDM.impl.null_physics_class import Null
from .barkan_and_luz_2007 import BarkanAndLuz2007
from .dansgaard_1964 import Dansgaard1964
from .picciotto_et_al_1960 import PicciottoEtAl1960
15 changes: 15 additions & 0 deletions PySDM/physics/isotope_meteoric_water_line/picciotto_et_al_1960.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
""" based on [Picciotto et al. 1960](https://doi.org/10.1038/187857a0)
where delta(2H)= slope_coeff * delta(18O) + intercept_coeff formulae is given
with swapped 2H and 18O in a paper
"""


class PicciottoEtAl1960: # pylint: disable=too-few-public-methods
def __init__(self, _):
pass

@staticmethod
def d18O_of_d2H(const, delta_2H):
return (
delta_2H - const.PICCIOTTO_18O_TO_2H_INTERCEPT_COEFF
) / const.PICCIOTTO_18O_TO_2H_SLOPE_COEFF
5 changes: 0 additions & 5 deletions PySDM/physics/isotope_meteoric_water_line_excess/__init__.py

This file was deleted.

8 changes: 8 additions & 0 deletions PySDM/physics/isotope_temperature_inference/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
formulae for inferring atmospheric temperatures from (ice core) water isotopic composition
"""

from PySDM.impl.null_physics_class import Null
from PySDM.physics.isotope_temperature_inference.picciotto_et_al_1960 import (
PicciottoEtAl1960,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
""" based on [Picciotto et al. 1960](https://doi.org/10.1038/187857a0)
where delta(T)=-(a*T + b) formulae given, here cast as T(delta)=(-delta-b)/a """


class PicciottoEtAl1960: # pylint: disable=too-few-public-methods
def __init__(self, _):
pass

@staticmethod
def temperature_from_delta_18O(const, delta_18O):
return const.T0 + (-delta_18O - const.PICCIOTTO_18O_B) / const.PICCIOTTO_18O_A

@staticmethod
def temperature_from_delta_2H(const, delta_2H):
return const.T0 + (-delta_2H - const.PICCIOTTO_2H_B) / const.PICCIOTTO_2H_A
16 changes: 13 additions & 3 deletions docs/bibliography.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
},
"https://doi.org/10.3402/tellusa.v16i4.8993": {
"usages": [
"PySDM/physics/isotope_meteoric_water_line_excess/dansgaard_1964.py"
"PySDM/physics/isotope_meteoric_water_line/dansgaard_1964.py"
],
"label": "Dansgaard 1964 (Tellus A 16)",
"title": "Stable isotopes in precipitation"
Expand Down Expand Up @@ -481,7 +481,7 @@
"https://doi.org/10.1002/rcm.3180": {
"usages": [
"PySDM/physics/constants_defaults.py",
"PySDM/physics/isotope_meteoric_water_line_excess/barkan_and_luz_2007.py"
"PySDM/physics/isotope_meteoric_water_line/barkan_and_luz_2007.py"
],
"label": "Barkan & Luz 2007 (Rapid Commun. Mass Spectrom. 21)",
"title": "Diffusivity fractionations of H<sub>2</sub><sup>16</sup>O/H<sub>2</sub><sup>17</sup>O and H<sub>2</sub><sup>16</sup>O/H<sub>2</sub><sup>18</sup>O in air and their implications for isotope hydrology"
Expand Down Expand Up @@ -616,7 +616,7 @@
},
"https://doi.org/10.1126/science.133.3465.1702": {
"usages": [
"tests/unit_tests/physics/test_isotope_meteoric_water_line_excess.py",
"tests/unit_tests/physics/test_isotope_meteoric_water_line.py",
"PySDM/physics/constants_defaults.py"
],
"label": "Craig 1961 (Science 133)",
Expand Down Expand Up @@ -691,5 +691,15 @@
"usages": ["PySDM/physics/saturation_vapour_pressure/wexler_1976.py"],
"title": "Vapor Pressure Formulation for Water in Range 0 to f 00 °C. A Revision",
"label": "Wexler 1976 (J. Res. NBS A Phys. Ch. 80A)"
},
"https://doi.org/10.1038/187857a0": {
"usages": [
"PySDM/physics/constants_defaults.py",
"PySDM/physics/isotope_temperature_inference/picciotto_et_al_1960.py",
"PySDM/physics/isotope_meteoric_water_line/picciotto_et_al_1960.py",
"tests/unit_tests/physics/test_isotope_temperature_inference.py"
],
"title": "Isotopic Composition and Temperature of Formation of Antarctic Snows",
"label": "Picciotto et al. 1960 (Nature 187)"
}
}
6 changes: 4 additions & 2 deletions docs/generate_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ def check_urls(urls_from_json):
for url in unique_urls_found
}
for url in unique_urls_read:
assert url_usages_found[url] == sorted(urls_from_json[url]["usages"]), (
f"{url} usages mismatch:\n"
assert set(url_usages_found[url]) == set(
sorted(urls_from_json[url]["usages"])
), (
f"{url} usages mismatch (please fix docs/bibliography.json):\n"
f"\texpected: {url_usages_found[url]}\n"
f"\tactual: {urls_from_json[url]['usages']}"
)
Expand Down
6 changes: 3 additions & 3 deletions examples/PySDM_examples/Gedzelman_and_Arnold_1994/fig_2.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -11496,11 +11496,11 @@
"formulae = Formulae(\n",
" isotope_equilibrium_fractionation_factors='BarkanAndLuz2005+HoritaAndWesolowski1994',\n",
" isotope_diffusivity_ratios='HellmannAndHarvey2020',\n",
" isotope_meteoric_water_line_excess='BarkanAndLuz2007+Dansgaard1964',\n",
" isotope_meteoric_water_line='BarkanAndLuz2007+Dansgaard1964',\n",
" isotope_ratio_evolution='GedzelmanAndArnold1994',\n",
")\n",
"deltas_18O = [formulae.isotope_meteoric_water_line_excess.d18O_of_d2H(d2H) for d2H in DELTAS_2H]\n",
"deltas_17O = [formulae.isotope_meteoric_water_line_excess.d17O_of_d18O(d18O) for d18O in deltas_18O]\n",
"deltas_18O = [formulae.isotope_meteoric_water_line.d18O_of_d2H(d2H) for d2H in DELTAS_2H]\n",
"deltas_17O = [formulae.isotope_meteoric_water_line.d17O_of_d18O(d18O) for d18O in deltas_18O]\n",
"\n",
"fig, axs = pyplot.subplots(3, 3, figsize=(10,8), sharex=False, sharey=True, tight_layout=True) \n",
"\n",
Expand Down
4 changes: 2 additions & 2 deletions examples/PySDM_examples/Graf_et_al_2019/Table_1.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"source": [
"formulae = Formulae(\n",
" isotope_equilibrium_fractionation_factors='Majoube1970+Majoube1971+MerlivatAndNief1967',\n",
" isotope_meteoric_water_line_excess='Dansgaard1964'\n",
" isotope_meteoric_water_line='Dansgaard1964'\n",
")\n",
"const = formulae.constants\n",
"\n",
Expand All @@ -90,7 +90,7 @@
" '18O_s': formulae.isotope_equilibrium_fractionation_factors.alpha_i_18O,\n",
" '2H_s': formulae.isotope_equilibrium_fractionation_factors.alpha_i_2H\n",
"}\n",
"excess_d = formulae.isotope_meteoric_water_line_excess.excess_d\n",
"excess_d = formulae.isotope_meteoric_water_line.excess_d\n",
"\n",
"CASES = {\n",
" 'A': {'18O': -10 * const.PER_MILLE, '2H': -80 * const.PER_MILLE},\n",
Expand Down
4 changes: 2 additions & 2 deletions examples/PySDM_examples/Pierchala_et_al_2022/fig_3.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"source": [
"formulae = Formulae(\n",
" isotope_equilibrium_fractionation_factors='BarkanAndLuz2005+HoritaAndWesolowski1994',\n",
" isotope_meteoric_water_line_excess='Dansgaard1964+BarkanAndLuz2007',\n",
" isotope_meteoric_water_line='Dansgaard1964+BarkanAndLuz2007',\n",
" isotope_ratio_evolution='RayleighDistillation'\n",
")\n",
"const = formulae.constants\n",
Expand Down Expand Up @@ -118,7 +118,7 @@
"alpha_l_2H = alphas.alpha_l_2H(T=T)\n",
"alpha_l_17O = alphas.alpha_l_17O(np.nan, alpha_l_18O=alpha_l_18O)\n",
"\n",
"excess = formulae.isotope_meteoric_water_line_excess\n",
"excess = formulae.isotope_meteoric_water_line\n",
"\n",
"deltas = {}\n",
"enrichments = {}\n",
Expand Down
4 changes: 2 additions & 2 deletions examples/PySDM_examples/Pierchala_et_al_2022/fig_4.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"\n",
"formulae = Formulae(\n",
" isotope_equilibrium_fractionation_factors='BarkanAndLuz2005+HoritaAndWesolowski1994',\n",
" isotope_meteoric_water_line_excess='Dansgaard1964+BarkanAndLuz2007',\n",
" isotope_meteoric_water_line='Dansgaard1964+BarkanAndLuz2007',\n",
" isotope_ratio_evolution='RayleighDistillation'\n",
")\n",
"const = formulae.constants\n",
Expand Down Expand Up @@ -165,7 +165,7 @@
" axs[1].plot(\n",
" x,\n",
" in_unit(\n",
" formulae.isotope_meteoric_water_line_excess.excess_17O(deltas['17O'], deltas['18O']),\n",
" formulae.isotope_meteoric_water_line.excess_17O(deltas['17O'], deltas['18O']),\n",
" const.PER_MEG\n",
" ),\n",
" **kwargs\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"source": [
"formulae = Formulae(\n",
" isotope_equilibrium_fractionation_factors='HoritaAndWesolowski1994',\n",
" isotope_meteoric_water_line_excess='Dansgaard1964',\n",
" isotope_meteoric_water_line='Dansgaard1964',\n",
" isotope_ratio_evolution='MerlivatAndJouzel1979',\n",
")\n",
"BACKEND = CPU(formulae, override_jit_flags={'parallel': False})\n",
Expand All @@ -96,7 +96,7 @@
"}\n",
"\n",
"ARBITRARY_PARAMS = {\n",
" 'delta_18O_init': formulae.isotope_meteoric_water_line_excess.d18O_of_d2H(\n",
" 'delta_18O_init': formulae.isotope_meteoric_water_line.d18O_of_d2H(\n",
" delta_2H=FIG4_CAPTION_PARAMS['delta_2H_init']\n",
" ),\n",
" 'N_SUPER_DROPLETS': 1,\n",
Expand Down Expand Up @@ -12299,7 +12299,7 @@
" )\n",
" axs[plot_row, 3].plot(\n",
" in_unit(\n",
" formulae.isotope_meteoric_water_line_excess.excess_d(delta_2H=deltas[\"2H\"], delta_18O=deltas[\"18O\"]),\n",
" formulae.isotope_meteoric_water_line.excess_d(delta_2H=deltas[\"2H\"], delta_18O=deltas[\"18O\"]),\n",
" const.PER_MILLE\n",
" ),\n",
" temp_C[level_indices['CB']:],\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_bottom_panel(notebook_local_variables, RH, delta_18O, excess_17O):
np.testing.assert_approx_equal(
actual=notebook_local_variables[
"formulae"
].isotope_meteoric_water_line_excess.excess_17O(
].isotope_meteoric_water_line.excess_17O(
deltas_per_rh[RH]["17O"][index], deltas_per_rh[RH]["18O"][index]
),
desired=excess_17O,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
def test_cracow_water_excesses():
"""checking if d-excess and 17O-excess values match those computed from deltas"""
# arrange
formulae = Formulae(
isotope_meteoric_water_line_excess="Dansgaard1964+BarkanAndLuz2007"
)
sut = formulae.isotope_meteoric_water_line_excess
formulae = Formulae(isotope_meteoric_water_line="Dansgaard1964+BarkanAndLuz2007")
sut = formulae.isotope_meteoric_water_line

# act/assert
np.testing.assert_approx_equal(
Expand Down
Loading

0 comments on commit 86ddb1d

Please sign in to comment.