Skip to content

Commit 2b553f3

Browse files
authored
Merge pull request #59 from axiom-data-science/schema-improvements
JSON Schema oil type improvements and related updates and refactors
2 parents 80bd630 + 5e7ae7b commit 2b553f3

File tree

17 files changed

+2885
-1594
lines changed

17 files changed

+2885
-1594
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ repos:
5454
- id: codespell
5555
args:
5656
- --quiet-level=2
57-
exclude: 'particle_tracking_manager/models/opendrift/enums.py'
57+
exclude: 'particle_tracking_manager/models/opendrift/enums/oil_types.py'

docs/environment.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ dependencies:
1010
- appdirs
1111
- cmocean
1212
- fastparquet
13+
- importlib_resources # should update past opendrift 1.12 and remove this when possible
1314
- numpy
1415
- xarray
1516
- kerchunk==0.2.7
1617
- numpydoc
17-
- opendrift==1.13.0
18+
- opendrift <=1.13.0
1819
# These are needed for the docs themselves
1920
- furo
2021
- jupytext

docs/tutorial.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ There are also specific seeding options for this model:
211211

212212
```{code-cell} ipython3
213213
m = ptm.OpenDriftModel(drift_model="OpenOil", lon=-89.85, lat=28.08, number=10, steps=45,
214-
z=-10, do3D=True, oil_type=('EC00561', 'Cook Inlet [2003]'),
214+
z=-10, do3D=True, oil_type="EC00561",
215215
start_time="2009-11-19T12:00", ocean_model="TXLA",
216216
ocean_model_local=False,
217217
)
@@ -220,13 +220,24 @@ m.o.set_config('environment:constant:x_wind', -1)
220220
m.o.set_config('environment:constant:y_wind', 1)
221221
```
222222

223-
List available oil types from NOAA's ADIOS database (or check the database online):
223+
Note that `oil_type` was input by its oil id, in order to disambiguate the oils in ADIOS.
224+
225+
List of available oil types can be found in the
226+
1. NOAA's ADIOS database https://adios.orr.noaa.gov/oils
227+
2. or in the library's `OIL_ID_TO_NAME` dictionary:
228+
```{code-cell} ipython3
229+
ptm.models.opendrift.enums.oil_types.OIL_ID_TO_NAME
230+
```
231+
232+
You can also find the oil IDs by name in said [database](https://adios.orr.noaa.gov/oils)
233+
or in the library's `NAME_TO_OIL_ID` dictionary. E.g.:
224234
225235
```{code-cell} ipython3
226-
ptm.OpenOilModelConfig.model_json_schema()["$defs"]["OilTypeEnum"]["enum"]
236+
ptm.models.opendrift.enums.oil_types.NAME_TO_OIL_ID["ALASKA NORTH SLOPE"]
227237
```
228238

229-
Note that `oil_type` was input as a tuple containing the oil id and name, in order to disambiguate the oils in ADIOS. You can instead refer to the `oil_type` by its id, for example in this case `oil_tye='EC00561'` would work.
239+
Keep in mind that some oil types share the same name which is why `NAME_TO_OIL_ID`
240+
contains lists of IDs.
230241

231242
The configuration parameters for this simulation are:
232243

docs/whats_new.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
## Unreleased
44

5-
* Fix kerchunk JSON file filtering.
5+
* Fixed kerchunk JSON file filtering.
66
* Added CIOFS3 as ocean model option.
7+
* Refactored `OilTypeEnum` so that it's value is only the oil ID. Also add the
8+
"oneOf" json schema mapping directly to the field's `json_schema_extra` so that
9+
it is part of the schema by default.
10+
711

812
## v0.12.2 (April 15, 2025)
913

particle_tracking_manager/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,24 @@
1010
logging.getLogger("numcodecs").setLevel(logging.WARNING)
1111

1212
from .config_the_manager import TheManagerConfig
13+
from .models import opendrift as opendrift_models
1314
from .models.opendrift.config_opendrift import (
1415
LarvalFishModelConfig,
1516
LeewayModelConfig,
1617
OceanDriftModelConfig,
1718
OpenDriftConfig,
1819
OpenOilModelConfig,
1920
)
20-
from .models.opendrift.enums import ModifyOilTypeJsonSchema
2121
from .models.opendrift.opendrift import OpenDriftModel
22+
23+
24+
__all__ = [
25+
"TheManagerConfig",
26+
"LarvalFishModelConfig",
27+
"LeewayModelConfig",
28+
"OceanDriftModelConfig",
29+
"OpenDriftConfig",
30+
"OpenOilModelConfig",
31+
"OpenDriftModel",
32+
"opendrift_models",
33+
]

particle_tracking_manager/config_ocean_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def open_dataset(self, drop_vars: list) -> xr.Dataset:
129129

130130
def create_ocean_model_simulation(
131131
ocean_model: OceanModelConfig,
132-
) -> OceanModelSimulation:
132+
) -> type[OceanModelSimulation]:
133133
"""Create an ocean model simulation object."""
134134
ocean_model_name = ocean_model.name
135135
simulation_model = create_model(

particle_tracking_manager/config_the_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ class TheManagerConfig(BaseModel):
232232
)
233233

234234
model_config = {
235-
"validate_defaults": True,
235+
"validate_default": True,
236+
# Field values will be returned as the `enum.value` - a string in most our cases
236237
"use_enum_values": True,
237238
"extra": "forbid",
238239
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
"""Options for models."""
2+
3+
from .opendrift import *

particle_tracking_manager/models/opendrift/config_opendrift.py

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from pathlib import Path
88

99
# Third-party imports
10-
from pydantic import Field, field_validator, model_validator
10+
from pydantic import Field, model_validator
1111
from pydantic.fields import FieldInfo
1212
from typing_extensions import Self
1313

@@ -18,7 +18,6 @@
1818
DiffusivityModelEnum,
1919
DriftModelEnum,
2020
DropletSizeDistributionEnum,
21-
ModifyOilTypeJsonSchema,
2221
ObjectTypeEnum,
2322
OilTypeEnum,
2423
PlotTypeEnum,
@@ -158,13 +157,6 @@ class OpenDriftConfig(TheManagerConfig):
158157
"extra": "forbid",
159158
}
160159

161-
@classmethod
162-
def model_json_schema(cls, **kwargs) -> dict:
163-
"""Override the method to customize the JSON schema to include customization of oil_type."""
164-
return super().model_json_schema(
165-
schema_generator=ModifyOilTypeJsonSchema, **kwargs
166-
)
167-
168160
@model_validator(mode="after")
169161
def check_interpolator_filename(self) -> Self:
170162
"""Check if interpolator_filename is set correctly."""
@@ -489,10 +481,14 @@ class OpenOilModelConfig(OceanDriftModelConfig):
489481
drift_model: DriftModelEnum = DriftModelEnum.OpenOil # .value
490482

491483
oil_type: OilTypeEnum = Field(
492-
default=OilTypeEnum["AD04012"], # .value,
484+
default=OilTypeEnum.AD04012, # .value,
493485
description="Oil type to be used for the simulation, from the NOAA ADIOS database.",
494486
title="Oil Type",
495-
json_schema_extra={"od_mapping": "seed:oil_type", "ptm_level": 1},
487+
json_schema_extra={
488+
"od_mapping": "seed:oil_type",
489+
"ptm_level": 1,
490+
"oneOf": [{"const": oil.value, "title": oil.title} for oil in OilTypeEnum],
491+
},
496492
)
497493

498494
m3_per_hour: float = Field(
@@ -645,20 +641,6 @@ class OpenOilModelConfig(OceanDriftModelConfig):
645641
OceanDriftModelConfig.model_fields["vertical_mixing"], Field(default=True)
646642
)
647643

648-
@field_validator("oil_type", mode="before")
649-
def map_id_to_oil_type_tuple(cls, v):
650-
"""Map input oil type to enum name (which is the oil type id)."""
651-
if (
652-
v in OilTypeEnum.__members__
653-
): # Check if it matches an Enum name (which is the oil type id)
654-
return OilTypeEnum[v] # then return id
655-
else:
656-
return v # return the original value
657-
# for enum_member in OilTypeEnum: # Check if it matches an Enum value (which is the oil type name/title)
658-
# if enum_member.value == v:
659-
# return enum_member # then return id
660-
raise ValueError(f"Invalid value or name '{v}' for OilTypeEnum")
661-
662644

663645
class LarvalFishModelConfig(OceanDriftModelConfig):
664646
"""Larval fish model configuration for OpenDrift."""
@@ -715,8 +697,8 @@ class LarvalFishModelConfig(OceanDriftModelConfig):
715697
},
716698
)
717699

718-
length: float = Field(
719-
default=0,
700+
length: float | None = Field(
701+
default=None,
720702
description="Seeding value of length. This is not currently used.",
721703
title="Length",
722704
gt=0,

0 commit comments

Comments
 (0)