Skip to content

Commit 4b59f90

Browse files
Merge branch 'v4-dev' into time_dt_as_float
2 parents 44278c8 + 54fbc40 commit 4b59f90

File tree

7 files changed

+49
-13
lines changed

7 files changed

+49
-13
lines changed

docs/user_guide/examples/tutorial_unitconverters.ipynb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
"cell_type": "markdown",
147147
"metadata": {},
148148
"source": [
149-
"So the U field has a `GeographicPolar` UnitConverter object, the V field has a `Geographic` UnitConverter and the `temp` field has a `UnitConverter` object.\n",
149+
"So the U field has a `GeographicPolar` UnitConverter object, the V field has a `Geographic` UnitConverter and the `temp` field has a `Unity` object.\n",
150150
"\n",
151151
"Indeed, if we multiply the value of the V field with 1852 \\* 60 (the number of meters in 1 degree of latitude), we get the expected 1 m/s.\n"
152152
]
@@ -248,7 +248,7 @@
248248
"cell_type": "markdown",
249249
"metadata": {},
250250
"source": [
251-
"Indeed, in this case all Fields have the same default `UnitConverter` object.\n"
251+
"Indeed, in this case all Fields have the same default `Unity` object.\n"
252252
]
253253
},
254254
{
@@ -296,7 +296,7 @@
296296
"kh_meridional_field = parcels.Field(\n",
297297
" \"Kh_meridional\",\n",
298298
" ds[\"Kh_meridional\"],\n",
299-
" grid=grid,\n",
299+
" grid=fieldset.U.grid,\n",
300300
" interp_method=parcels.interpolators.XLinear,\n",
301301
")\n",
302302
"\n",
@@ -348,7 +348,7 @@
348348
"| `\"V\"` | `Geographic` | $1852 \\cdot 60$ | 1 |\n",
349349
"| `\"Kh_zonal\"` | `GeographicPolarSquare` | $(1852 \\cdot 60 \\cdot \\cos(lat \\cdot \\frac{\\pi}{180}))^2$ | 1 |\n",
350350
"| `\"Kh_meridional\"` | `GeographicSquare` | $(1852 \\cdot 60)^2$ | 1 |\n",
351-
"| All other fields | `UnitConverter` | 1 | 1 |\n",
351+
"| All other fields | `Unity` | 1 | 1 |\n",
352352
"\n",
353353
"Only four Field names are recognised and assigned an automatic UnitConverter object. This means that things might go very wrong when e.g. a velocity field is not called `U` or `V`.\n",
354354
"\n",

docs/user_guide/v4-migration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@ Version 4 of Parcels is unreleased at the moment. The information in this migrat
4343
## GridSet
4444

4545
- `GridSet` is now a list, so change `fieldset.gridset.grids[0]` to `fieldset.gridset[0]`.
46+
47+
## UnitConverters
48+
49+
- The default `UnitConverter` is now called `Unity()`

src/parcels/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
GeographicPolar,
1515
GeographicPolarSquare,
1616
GeographicSquare,
17-
UnitConverter,
17+
Unity,
1818
)
1919
from parcels._core.field import Field, VectorField
2020
from parcels._core.fieldset import FieldSet
@@ -66,7 +66,7 @@
6666
"GeographicPolar",
6767
"GeographicPolarSquare",
6868
"GeographicSquare",
69-
"UnitConverter",
69+
"Unity",
7070
# Status codes and errors
7171
"AllParcelsErrorCodes",
7272
"FieldInterpolationError",

src/parcels/_core/converters.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from abc import ABC, abstractmethod
34
from math import pi
45

56
import numpy as np
@@ -11,6 +12,7 @@
1112
"GeographicPolarSquare",
1213
"GeographicSquare",
1314
"UnitConverter",
15+
"Unity",
1416
"_convert_to_flat_array",
1517
"_unitconverters_map",
1618
]
@@ -27,12 +29,23 @@ def _convert_to_flat_array(var: npt.ArrayLike) -> npt.NDArray:
2729
return np.array(var).flatten()
2830

2931

30-
class UnitConverter:
31-
"""Interface class for spatial unit conversion during field sampling that performs no conversion."""
32-
32+
class UnitConverter(ABC):
3333
source_unit: str | None = None
3434
target_unit: str | None = None
3535

36+
@abstractmethod
37+
def to_target(self, value, z, y, x): ...
38+
39+
@abstractmethod
40+
def to_source(self, value, z, y, x): ...
41+
42+
43+
class Unity(UnitConverter):
44+
"""Interface class for spatial unit conversion during field sampling that performs no conversion."""
45+
46+
source_unit: None
47+
target_unit: None
48+
3649
def to_target(self, value, z, y, x):
3750
return value
3851

src/parcels/_core/field.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from parcels._core.converters import (
1212
UnitConverter,
13+
Unity,
1314
_unitconverters_map,
1415
)
1516
from parcels._core.index_search import GRID_SEARCH_ERROR, LEFT_OUT_OF_BOUNDS, RIGHT_OUT_OF_BOUNDS, _search_time_index
@@ -135,7 +136,7 @@ def __init__(
135136
self.igrid = -1 # Default the grid index to -1
136137

137138
if self.grid._mesh == "flat" or (self.name not in _unitconverters_map.keys()):
138-
self.units = UnitConverter()
139+
self.units = Unity()
139140
elif self.grid._mesh == "spherical":
140141
self.units = _unitconverters_map[self.name]
141142

tests-v3/test_fieldset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
Variable,
1414
)
1515
from parcels.field import VectorField
16-
from parcels.tools.converters import GeographicPolar, UnitConverter
16+
from parcels.tools.converters import GeographicPolar, Unity
1717
from tests.utils import TEST_DATA
1818

1919

@@ -119,7 +119,7 @@ def test_field_from_netcdf_fieldtypes():
119119

120120
# first try without setting fieldtype
121121
fset = FieldSet.from_nemo(filenames, variables, dimensions)
122-
assert isinstance(fset.varU.units, UnitConverter)
122+
assert isinstance(fset.varU.units, Unity)
123123

124124
# now try with setting fieldtype
125125
fset = FieldSet.from_nemo(filenames, variables, dimensions, fieldtype={"varU": "U", "varV": "V"})

tests/test_diffusion.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@
44
import pytest
55
from scipy import stats
66

7-
from parcels import Field, FieldSet, Particle, ParticleSet, Variable, VectorField, XGrid
7+
from parcels import (
8+
Field,
9+
FieldSet,
10+
GeographicPolarSquare,
11+
GeographicSquare,
12+
Particle,
13+
ParticleSet,
14+
Unity,
15+
Variable,
16+
VectorField,
17+
XGrid,
18+
)
819
from parcels._core.utils.time import timedelta_to_float
920
from parcels._datasets.structured.generated import simple_UV_dataset
1021
from parcels.interpolators import XLinear
@@ -29,6 +40,13 @@ def test_fieldKh_Brownian(mesh):
2940
fieldset.add_constant_field("Kh_zonal", kh_zonal, mesh=mesh)
3041
fieldset.add_constant_field("Kh_meridional", kh_meridional, mesh=mesh)
3142

43+
if mesh == "spherical":
44+
assert isinstance(fieldset.Kh_zonal.units, GeographicPolarSquare)
45+
assert isinstance(fieldset.Kh_meridional.units, GeographicSquare)
46+
else:
47+
assert isinstance(fieldset.Kh_zonal.units, Unity)
48+
assert isinstance(fieldset.Kh_meridional.units, Unity)
49+
3250
npart = 100
3351
runtime = np.timedelta64(2, "h")
3452

0 commit comments

Comments
 (0)