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..74403732 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -2,8 +2,7 @@ from .do_expedition import do_expedition from .input_data import InputData -from .instrument_type import InstrumentType -from .schedule import Schedule +from .schedule import Schedule, Waypoint from .ship_config import ( ADCPConfig, ArgoFloatConfig, @@ -13,7 +12,6 @@ ShipUnderwaterSTConfig, ) from .space_time_region import SpaceTimeRegion -from .waypoint import Waypoint __all__ = [ "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..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 .instrument_type import InstrumentType +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/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..df36b8b2 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -13,10 +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 .waypoint import Waypoint +from .schedule import Schedule, Waypoint +from .ship_config import InstrumentType, ShipConfig @dataclass diff --git a/src/virtualship/expedition/waypoint.py b/src/virtualship/expedition/waypoint.py deleted file mode 100644 index 018ccecb..00000000 --- a/src/virtualship/expedition/waypoint.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Waypoint class.""" - -from datetime import datetime - -from pydantic import BaseModel, field_serializer - -from ..location import Location -from .instrument_type import InstrumentType - - -class Waypoint(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") - 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 c798a3dd..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.instrument_type import InstrumentType - 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") 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