Skip to content

Commit 27a1288

Browse files
Merge branch 'v4-dev' into feature/from_fesom2
2 parents 25fa2d3 + 4330de3 commit 27a1288

File tree

8 files changed

+173
-609
lines changed

8 files changed

+173
-609
lines changed

.github/ci/recipe.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,8 @@ requirements:
3131
- python >=3.11
3232
- cftime >=1.6.3
3333
- dask >=2024.5.1
34-
- matplotlib-base >=2.0.2
3534
- netcdf4 >=1.7.2
3635
- numpy >=2.1.0
37-
- platformdirs
38-
- pytest
39-
- trajan
4036
- tqdm >=4.50.0
4137
- xarray >=2024.5.0
4238
- cf_xarray >=0.8.6
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Using the `gsw` toolbox to compute density"
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"id": "1",
14+
"metadata": {},
15+
"source": [
16+
"This tutorial shows how to use the [`gsw` toolbox](https://teos-10.github.io/GSW-Python/) (the Gibbs SeaWater Oceanographic Toolbox of TEOS-10) within Parcels to compute density from temperature and salinity fields. The `gsw` toolbox can be installed via `conda install gsw`."
17+
]
18+
},
19+
{
20+
"cell_type": "markdown",
21+
"id": "2",
22+
"metadata": {},
23+
"source": [
24+
"First, load the necessary libraries and the data:"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"id": "3",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"import gsw # The package to calculate density from temperature, salinity and depth\n",
35+
"import numpy as np\n",
36+
"import xarray as xr\n",
37+
"\n",
38+
"import parcels\n",
39+
"\n",
40+
"# Load the CopernicusMarine data in the Agulhas region from the example_datasets\n",
41+
"example_dataset_folder = parcels.download_example_dataset(\n",
42+
" \"CopernicusMarine_data_for_Argo_tutorial\"\n",
43+
")\n",
44+
"\n",
45+
"ds = xr.open_mfdataset(f\"{example_dataset_folder}/*.nc\", combine=\"by_coords\")\n",
46+
"\n",
47+
"# TODO check how we can get good performance without loading full dataset in memory\n",
48+
"ds.load() # load the dataset into memory\n",
49+
"\n",
50+
"fieldset = parcels.FieldSet.from_copernicusmarine(ds)"
51+
]
52+
},
53+
{
54+
"cell_type": "markdown",
55+
"id": "4",
56+
"metadata": {},
57+
"source": [
58+
"Now, define a custom Particle class that includes temperature, salinity, and density as variables, and create a ParticleSet with one particle at a known location:"
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": null,
64+
"id": "5",
65+
"metadata": {},
66+
"outputs": [],
67+
"source": [
68+
"GSWParticle = parcels.Particle.add_variable(\n",
69+
" [\n",
70+
" parcels.Variable(\"temp\", dtype=np.float32, initial=np.nan),\n",
71+
" parcels.Variable(\"salt\", dtype=np.float32, initial=np.nan),\n",
72+
" parcels.Variable(\"density\", dtype=np.float32, initial=np.nan),\n",
73+
" ]\n",
74+
")\n",
75+
"\n",
76+
"# Initiate one Argo float in the Agulhas Current\n",
77+
"pset = parcels.ParticleSet(\n",
78+
" fieldset=fieldset,\n",
79+
" pclass=GSWParticle,\n",
80+
" lon=[32],\n",
81+
" lat=[-31],\n",
82+
" z=[200],\n",
83+
")"
84+
]
85+
},
86+
{
87+
"cell_type": "markdown",
88+
"id": "6",
89+
"metadata": {},
90+
"source": [
91+
"Now (as the core part of this tutorial) define a custom kernel that uses the `gsw` toolbox to compute density from temperature and salinity:"
92+
]
93+
},
94+
{
95+
"cell_type": "code",
96+
"execution_count": null,
97+
"id": "7",
98+
"metadata": {},
99+
"outputs": [],
100+
"source": [
101+
"def ParcelsGSW(particles, fieldset):\n",
102+
" particles.temp = fieldset.thetao[particles]\n",
103+
" particles.salt = fieldset.so[particles]\n",
104+
" pressure = gsw.p_from_z(-particles.z, particles.lat)\n",
105+
" particles.density = gsw.density.rho(particles.salt, particles.temp, pressure)"
106+
]
107+
},
108+
{
109+
"cell_type": "markdown",
110+
"id": "8",
111+
"metadata": {},
112+
"source": [
113+
"Finally, run the `ParcelsGSW` Kernel for one timestep and check (for Continuous Integration purposes) that the computed density is as expected:"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": null,
119+
"id": "9",
120+
"metadata": {},
121+
"outputs": [],
122+
"source": [
123+
"pset.execute(ParcelsGSW, runtime=np.timedelta64(1, \"s\"), dt=np.timedelta64(1, \"s\"))\n",
124+
"\n",
125+
"np.testing.assert_allclose(pset.density, [1026.8281], rtol=1e-5)\n",
126+
"\n",
127+
"print(\n",
128+
" f\"Temperature: {pset.temp[0]:.2f}, Salinity: {pset.salt[0]:.2f}, Density: {pset.density[0]:.2f}\"\n",
129+
")"
130+
]
131+
}
132+
],
133+
"metadata": {
134+
"kernelspec": {
135+
"display_name": "parcels",
136+
"language": "python",
137+
"name": "python3"
138+
},
139+
"language_info": {
140+
"codemirror_mode": {
141+
"name": "ipython",
142+
"version": 3
143+
},
144+
"file_extension": ".py",
145+
"mimetype": "text/x-python",
146+
"name": "python",
147+
"nbconvert_exporter": "python",
148+
"pygments_lexer": "ipython3",
149+
"version": "3.13.5"
150+
}
151+
},
152+
"nbformat": 4,
153+
"nbformat_minor": 5
154+
}

pixi.toml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
[workspace]
22
name = "Parcels"
3-
preview = ["pixi-build"]
43
channels = ["conda-forge"]
54
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64"]
65

7-
[package]
8-
name = "parcels"
9-
version = "dynamic" # dynamic versioning needs better support in pixi https://github.com/prefix-dev/pixi/issues/2923#issuecomment-2598460666 . Putting `version = "dynamic"` here for now until pixi recommends something else.
10-
license = "MIT" # can remove this once https://github.com/prefix-dev/pixi-build-backends/issues/397 is resolved
11-
12-
[package.build]
13-
backend = { name = "pixi-build-python", version = "==0.4.0" }
14-
15-
[package.host-dependencies]
16-
setuptools = "*"
17-
setuptools_scm = "*"
6+
# TODO: Re-enable pixi-build once https://github.com/prefix-dev/pixi-build-backends/issues/411 is fixed, and remove pypi install of Parcels
7+
# preview = ["pixi-build"]
8+
# [package]
9+
# name = "parcels"
10+
# version = "dynamic" # dynamic versioning needs better support in pixi https://github.com/prefix-dev/pixi/issues/2923#issuecomment-2598460666 . Putting `version = "dynamic"` here for now until pixi recommends something else.
11+
# license = "MIT" # can remove this once https://github.com/prefix-dev/pixi-build-backends/issues/397 is resolved
12+
#
13+
# [package.build]
14+
# backend = { name = "pixi-build-python", version = "==0.4.0" }
15+
#
16+
# [package.host-dependencies]
17+
# setuptools = "*"
18+
# setuptools_scm = "*"
1819

1920
[environments]
2021
test-latest = { features = ["test"], solve-group = "test" }
@@ -28,7 +29,7 @@ pre-commit = { features = ["pre-commit"], no-default-feature = true }
2829

2930
[dependencies] # keep section in sync with pyproject.toml dependencies
3031
python = ">=3.11,<3.13"
31-
parcels = { path = "." }
32+
# parcels = { path = "." }
3233
netcdf4 = ">=1.7.2"
3334
numpy = ">=2.1.0"
3435
tqdm = ">=4.50.0"
@@ -41,6 +42,9 @@ cf_xarray = ">=0.8.6"
4142
cftime = ">=1.6.3"
4243
pooch = ">=1.8.0"
4344

45+
[pypi-dependencies]
46+
parcels = { path = ".", editable = true }
47+
4448
[feature.minimum.dependencies]
4549
python = "==3.11"
4650
netcdf4 = "==1.7.2"
@@ -77,6 +81,7 @@ tests-notebooks = "pytest --nbval-lax -k 'argo' docs/examples"
7781
jupyter = "*"
7882
trajan = "*"
7983
matplotlib-base = ">=2.0.2"
84+
gsw = "*"
8085

8186
[feature.docs.dependencies]
8287
numpydoc = "!=1.9.0"

src/parcels/_core/kernel.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
import math # noqa: F401
4-
import random # noqa: F401
53
import types
64
import warnings
75
from typing import TYPE_CHECKING
@@ -116,8 +114,6 @@ def remove_deleted(self, pset):
116114
def add_positionupdate_kernels(self):
117115
# Adding kernels that set and update the coordinate changes
118116
def Setcoords(particles, fieldset): # pragma: no cover
119-
import numpy as np # noqa
120-
121117
particles.lon += particles.dlon
122118
particles.lat += particles.dlat
123119
particles.z += particles.dz

src/parcels/_tutorial.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
],
4848
"CopernicusMarine_data_for_Argo_tutorial": [
4949
"cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m_uo-vo_31.00E-33.00E_33.00S-30.00S_0.49-2225.08m_2024-01-01-2024-02-01.nc",
50+
"cmems_mod_glo_phy-so_anfc_0.083deg_P1D-m_so_31.00E-33.00E_33.00S-30.00S_0.49-2225.08m_2024-01-01-2024-02-01.nc",
5051
"cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m_thetao_31.00E-33.00E_33.00S-30.00S_0.49-2225.08m_2024-01-01-2024-02-01.nc",
5152
],
5253
"DecayingMovingEddy_data": [

0 commit comments

Comments
 (0)