From 975d8283c3b05b41e7ebf289a8f57cfbf47ea748 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Fri, 2 May 2025 15:38:29 +0200 Subject: [PATCH 1/2] Move InstrumentType to ship_config.py --- src/virtualship/cli/_fetch.py | 2 +- src/virtualship/expedition/__init__.py | 1 - src/virtualship/expedition/checkpoint.py | 2 +- src/virtualship/expedition/instrument_type.py | 12 ------------ src/virtualship/expedition/schedule.py | 2 +- src/virtualship/expedition/ship_config.py | 15 +++++++++++++-- src/virtualship/expedition/simulate_schedule.py | 3 +-- src/virtualship/expedition/waypoint.py | 10 ++++++---- src/virtualship/utils.py | 2 +- tests/test_mfp_to_yaml.py | 2 +- 10 files changed, 25 insertions(+), 26 deletions(-) delete mode 100644 src/virtualship/expedition/instrument_type.py diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 16712d38..2e09dec2 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -38,7 +38,7 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None be provided on prompt, via command line arguments, or via a YAML config file. Run `virtualship fetch` on an expedition for more info. """ - from virtualship.expedition.instrument_type import InstrumentType + from virtualship.expedition.ship_config import InstrumentType if sum([username is None, password is None]) == 1: raise ValueError("Both username and password must be provided when using CLI.") diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 9137f7b1..831371bd 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -2,7 +2,6 @@ from .do_expedition import do_expedition from .input_data import InputData -from .instrument_type import InstrumentType from .schedule import Schedule from .ship_config import ( ADCPConfig, diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index 75dd2356..be6079ef 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -7,8 +7,8 @@ import pydantic import yaml -from .instrument_type import InstrumentType from .schedule import Schedule +from .ship_config import InstrumentType class _YamlDumper(yaml.SafeDumper): diff --git a/src/virtualship/expedition/instrument_type.py b/src/virtualship/expedition/instrument_type.py deleted file mode 100644 index 82360c7b..00000000 --- a/src/virtualship/expedition/instrument_type.py +++ /dev/null @@ -1,12 +0,0 @@ -"""InstrumentType Enum.""" - -from enum import Enum - - -class InstrumentType(Enum): - """Types of instruments.""" - - CTD = "CTD" - DRIFTER = "DRIFTER" - ARGO_FLOAT = "ARGO_FLOAT" - XBT = "XBT" diff --git a/src/virtualship/expedition/schedule.py b/src/virtualship/expedition/schedule.py index 6c3bbfd1..5658f8d2 100644 --- a/src/virtualship/expedition/schedule.py +++ b/src/virtualship/expedition/schedule.py @@ -12,7 +12,7 @@ from parcels import FieldSet from .input_data import InputData -from .instrument_type import InstrumentType +from .ship_config import InstrumentType from .space_time_region import SpaceTimeRegion from .waypoint import Waypoint diff --git a/src/virtualship/expedition/ship_config.py b/src/virtualship/expedition/ship_config.py index b411443f..4f238b36 100644 --- a/src/virtualship/expedition/ship_config.py +++ b/src/virtualship/expedition/ship_config.py @@ -3,15 +3,26 @@ from __future__ import annotations from datetime import timedelta +from enum import Enum from pathlib import Path +from typing import TYPE_CHECKING import pydantic import yaml from virtualship.utils import _validate_numeric_mins_to_timedelta -from .instrument_type import InstrumentType -from .schedule import Schedule +if TYPE_CHECKING: + from .schedule import Schedule + + +class InstrumentType(Enum): + """Types of instruments.""" + + CTD = "CTD" + DRIFTER = "DRIFTER" + ARGO_FLOAT = "ARGO_FLOAT" + XBT = "XBT" class ArgoFloatConfig(pydantic.BaseModel): diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index fadfd2aa..db22bd71 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -13,9 +13,8 @@ from ..instruments.xbt import XBT from ..location import Location from ..spacetime import Spacetime -from .instrument_type import InstrumentType from .schedule import Schedule -from .ship_config import ShipConfig +from .ship_config import InstrumentType, ShipConfig from .waypoint import Waypoint diff --git a/src/virtualship/expedition/waypoint.py b/src/virtualship/expedition/waypoint.py index 018ccecb..9fb08a52 100644 --- a/src/virtualship/expedition/waypoint.py +++ b/src/virtualship/expedition/waypoint.py @@ -1,21 +1,23 @@ """Waypoint class.""" +from __future__ import annotations + from datetime import datetime -from pydantic import BaseModel, field_serializer +import pydantic from ..location import Location -from .instrument_type import InstrumentType +from .ship_config import InstrumentType -class Waypoint(BaseModel): +class Waypoint(pydantic.BaseModel): """A Waypoint to sail to with an optional time and an optional instrument.""" location: Location time: datetime | None = None instrument: InstrumentType | list[InstrumentType] | None = None - @field_serializer("instrument") + @pydantic.field_serializer("instrument") def serialize_instrument(self, instrument): """Ensure InstrumentType is serialized as a string (or list of strings).""" if isinstance(instrument, list): diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index c798a3dd..059685d4 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -139,8 +139,8 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 """ # Importing Schedule and related models from expedition module - from virtualship.expedition.instrument_type import InstrumentType from virtualship.expedition.schedule import Schedule + from virtualship.expedition.ship_config import InstrumentType from virtualship.expedition.space_time_region import ( SpaceTimeRegion, SpatialRange, diff --git a/tests/test_mfp_to_yaml.py b/tests/test_mfp_to_yaml.py index a3175185..3ef511f5 100644 --- a/tests/test_mfp_to_yaml.py +++ b/tests/test_mfp_to_yaml.py @@ -3,8 +3,8 @@ import pandas as pd import pytest -from virtualship.expedition.instrument_type import InstrumentType from virtualship.expedition.schedule import Schedule +from virtualship.expedition.ship_config import InstrumentType from virtualship.utils import mfp_to_yaml From 2811a82145f4eb57867dbe7329a98c0653854c76 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Fri, 2 May 2025 15:48:37 +0200 Subject: [PATCH 2/2] Move Waypoint to schedule.py --- src/virtualship/expedition/__init__.py | 3 +-- src/virtualship/expedition/schedule.py | 19 ++++++++++++-- .../expedition/simulate_schedule.py | 3 +-- src/virtualship/expedition/waypoint.py | 25 ------------------- src/virtualship/utils.py | 3 +-- tests/expedition/test_schedule.py | 3 +-- 6 files changed, 21 insertions(+), 35 deletions(-) delete mode 100644 src/virtualship/expedition/waypoint.py diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 831371bd..74403732 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -2,7 +2,7 @@ from .do_expedition import do_expedition from .input_data import InputData -from .schedule import Schedule +from .schedule import Schedule, Waypoint from .ship_config import ( ADCPConfig, ArgoFloatConfig, @@ -12,7 +12,6 @@ ShipUnderwaterSTConfig, ) from .space_time_region import SpaceTimeRegion -from .waypoint import Waypoint __all__ = [ "ADCPConfig", diff --git a/src/virtualship/expedition/schedule.py b/src/virtualship/expedition/schedule.py index 5658f8d2..79f14758 100644 --- a/src/virtualship/expedition/schedule.py +++ b/src/virtualship/expedition/schedule.py @@ -3,7 +3,7 @@ from __future__ import annotations import itertools -from datetime import timedelta +from datetime import datetime, timedelta from pathlib import Path import pydantic @@ -11,14 +11,29 @@ import yaml from parcels import FieldSet +from ..location import Location from .input_data import InputData from .ship_config import InstrumentType from .space_time_region import SpaceTimeRegion -from .waypoint import Waypoint projection: pyproj.Geod = pyproj.Geod(ellps="WGS84") +class Waypoint(pydantic.BaseModel): + """A Waypoint to sail to with an optional time and an optional instrument.""" + + location: Location + time: datetime | None = None + instrument: InstrumentType | list[InstrumentType] | None = None + + @pydantic.field_serializer("instrument") + def serialize_instrument(self, instrument): + """Ensure InstrumentType is serialized as a string (or list of strings).""" + if isinstance(instrument, list): + return [inst.value for inst in instrument] + return instrument.value if instrument else None + + class Schedule(pydantic.BaseModel): """Schedule of the virtual ship.""" diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index db22bd71..df36b8b2 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -13,9 +13,8 @@ from ..instruments.xbt import XBT from ..location import Location from ..spacetime import Spacetime -from .schedule import Schedule +from .schedule import Schedule, Waypoint from .ship_config import InstrumentType, ShipConfig -from .waypoint import Waypoint @dataclass diff --git a/src/virtualship/expedition/waypoint.py b/src/virtualship/expedition/waypoint.py deleted file mode 100644 index 9fb08a52..00000000 --- a/src/virtualship/expedition/waypoint.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Waypoint class.""" - -from __future__ import annotations - -from datetime import datetime - -import pydantic - -from ..location import Location -from .ship_config import InstrumentType - - -class Waypoint(pydantic.BaseModel): - """A Waypoint to sail to with an optional time and an optional instrument.""" - - location: Location - time: datetime | None = None - instrument: InstrumentType | list[InstrumentType] | None = None - - @pydantic.field_serializer("instrument") - def serialize_instrument(self, instrument): - """Ensure InstrumentType is serialized as a string (or list of strings).""" - if isinstance(instrument, list): - return [inst.value for inst in instrument] - return instrument.value if instrument else None diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index 059685d4..1d3203de 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -139,14 +139,13 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 """ # Importing Schedule and related models from expedition module - from virtualship.expedition.schedule import Schedule + from virtualship.expedition.schedule import Location, Schedule, Waypoint from virtualship.expedition.ship_config import InstrumentType from virtualship.expedition.space_time_region import ( SpaceTimeRegion, SpatialRange, TimeRange, ) - from virtualship.expedition.waypoint import Location, Waypoint # Read data from file coordinates_data = load_coordinates(coordinates_file_path) diff --git a/tests/expedition/test_schedule.py b/tests/expedition/test_schedule.py index 50c35d2f..eabcbd9a 100644 --- a/tests/expedition/test_schedule.py +++ b/tests/expedition/test_schedule.py @@ -5,9 +5,8 @@ import pytest from virtualship import Location -from virtualship.expedition import Waypoint from virtualship.expedition.do_expedition import _load_input_data -from virtualship.expedition.schedule import Schedule, ScheduleError +from virtualship.expedition.schedule import Schedule, ScheduleError, Waypoint from virtualship.utils import _get_ship_config projection = pyproj.Geod(ellps="WGS84")