From 7fa842c619b76c41accf9d871e3cbd40a10f6fdf Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:12:55 +0200 Subject: [PATCH 01/13] Move location.py and spacetime.py to models --- src/virtualship/__init__.py | 4 ++-- src/virtualship/expedition/schedule.py | 2 +- src/virtualship/expedition/simulate_schedule.py | 4 ++-- src/virtualship/instruments/adcp.py | 2 +- src/virtualship/instruments/argo_float.py | 2 +- src/virtualship/instruments/ctd.py | 2 +- src/virtualship/instruments/ctd_bgc.py | 2 +- src/virtualship/instruments/drifter.py | 2 +- src/virtualship/instruments/ship_underwater_st.py | 2 +- src/virtualship/instruments/xbt.py | 2 +- src/virtualship/{ => models}/location.py | 0 src/virtualship/{ => models}/spacetime.py | 0 12 files changed, 12 insertions(+), 12 deletions(-) rename src/virtualship/{ => models}/location.py (100%) rename src/virtualship/{ => models}/spacetime.py (100%) diff --git a/src/virtualship/__init__.py b/src/virtualship/__init__.py index 877fe4e1..755e03de 100644 --- a/src/virtualship/__init__.py +++ b/src/virtualship/__init__.py @@ -2,8 +2,8 @@ from importlib.metadata import version as _version -from .location import Location -from .spacetime import Spacetime +from .models.location import Location +from .models.spacetime import Spacetime try: __version__ = _version("virtualship") diff --git a/src/virtualship/expedition/schedule.py b/src/virtualship/expedition/schedule.py index 4ecd5e7c..77a9a113 100644 --- a/src/virtualship/expedition/schedule.py +++ b/src/virtualship/expedition/schedule.py @@ -12,7 +12,7 @@ import yaml from parcels import FieldSet -from ..location import Location +from ..models.location import Location from .ship_config import InstrumentType from .space_time_region import SpaceTimeRegion diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index 596d16a2..05756e78 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -12,8 +12,8 @@ from ..instruments.ctd_bgc import CTD_BGC from ..instruments.drifter import Drifter from ..instruments.xbt import XBT -from ..location import Location -from ..spacetime import Spacetime +from ..models.location import Location +from ..models.spacetime import Spacetime from .schedule import Schedule, Waypoint from .ship_config import InstrumentType, ShipConfig diff --git a/src/virtualship/instruments/adcp.py b/src/virtualship/instruments/adcp.py index 5563bdd2..44cb1518 100644 --- a/src/virtualship/instruments/adcp.py +++ b/src/virtualship/instruments/adcp.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/argo_float.py b/src/virtualship/instruments/argo_float.py index 2091098e..816d59b5 100644 --- a/src/virtualship/instruments/argo_float.py +++ b/src/virtualship/instruments/argo_float.py @@ -15,7 +15,7 @@ Variable, ) -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd.py b/src/virtualship/instruments/ctd.py index 6f76b408..1ecc5a16 100644 --- a/src/virtualship/instruments/ctd.py +++ b/src/virtualship/instruments/ctd.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd_bgc.py b/src/virtualship/instruments/ctd_bgc.py index cb218e3a..955a3ed5 100644 --- a/src/virtualship/instruments/ctd_bgc.py +++ b/src/virtualship/instruments/ctd_bgc.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/drifter.py b/src/virtualship/instruments/drifter.py index 2fd4180b..d2c3c099 100644 --- a/src/virtualship/instruments/drifter.py +++ b/src/virtualship/instruments/drifter.py @@ -7,7 +7,7 @@ import numpy as np from parcels import AdvectionRK4, FieldSet, JITParticle, ParticleSet, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ship_underwater_st.py b/src/virtualship/instruments/ship_underwater_st.py index 407055ad..ada68ad7 100644 --- a/src/virtualship/instruments/ship_underwater_st.py +++ b/src/virtualship/instruments/ship_underwater_st.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/xbt.py b/src/virtualship/instruments/xbt.py index 36a28471..ecd66ea5 100644 --- a/src/virtualship/instruments/xbt.py +++ b/src/virtualship/instruments/xbt.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..spacetime import Spacetime +from ..models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/location.py b/src/virtualship/models/location.py similarity index 100% rename from src/virtualship/location.py rename to src/virtualship/models/location.py diff --git a/src/virtualship/spacetime.py b/src/virtualship/models/spacetime.py similarity index 100% rename from src/virtualship/spacetime.py rename to src/virtualship/models/spacetime.py From 83f1e510e94186ecb43ab89fc17fe2e6c67c5508 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:18:53 +0200 Subject: [PATCH 02/13] Move ship_config to models --- src/virtualship/cli/_fetch.py | 2 +- src/virtualship/expedition/__init__.py | 2 +- src/virtualship/expedition/checkpoint.py | 2 +- src/virtualship/expedition/do_expedition.py | 14 +++++++------- src/virtualship/expedition/schedule.py | 5 +++-- .../expedition/simulate_measurements.py | 2 +- src/virtualship/expedition/simulate_schedule.py | 8 ++++---- .../{expedition => models}/ship_config.py | 2 +- src/virtualship/utils.py | 7 +++---- tests/cli/test_fetch.py | 2 +- tests/expedition/test_ship_config.py | 2 +- tests/test_mfp_to_yaml.py | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) rename src/virtualship/{expedition => models}/ship_config.py (99%) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index f07c5b92..c23d8d31 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.ship_config import InstrumentType + from virtualship.models.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 65b7cf11..50f9229c 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -3,7 +3,7 @@ from .do_expedition import do_expedition from .input_data import InputData from .schedule import Schedule, Waypoint -from .ship_config import ( +from ..models.ship_config import ( ADCPConfig, ArgoFloatConfig, CTD_BGCConfig, diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index be6079ef..9102edf5 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -8,7 +8,7 @@ import yaml from .schedule import Schedule -from .ship_config import InstrumentType +from ..models.ship_config import InstrumentType class _YamlDumper(yaml.SafeDumper): diff --git a/src/virtualship/expedition/do_expedition.py b/src/virtualship/expedition/do_expedition.py index 6d7d236f..1d0b31fd 100644 --- a/src/virtualship/expedition/do_expedition.py +++ b/src/virtualship/expedition/do_expedition.py @@ -17,7 +17,7 @@ from .expedition_cost import expedition_cost from .input_data import InputData from .schedule import Schedule -from .ship_config import ShipConfig +from ..models.ship_config import ShipConfig from .simulate_measurements import simulate_measurements from .simulate_schedule import ScheduleProblem, simulate_schedule @@ -84,9 +84,9 @@ def do_expedition(expedition_dir: str | Path, input_data: Path | None = None) -> os.makedirs(expedition_dir.joinpath("results")) # calculate expedition cost in US$ - assert schedule.waypoints[0].time is not None, ( - "First waypoint has no time. This should not be possible as it should have been verified before." - ) + assert ( + schedule.waypoints[0].time is not None + ), "First waypoint has no time. This should not be possible as it should have been verified before." time_past = schedule_results.time - schedule.waypoints[0].time cost = expedition_cost(schedule_results, time_past) with open(expedition_dir.joinpath("results", "cost.txt"), "w") as file: @@ -131,9 +131,9 @@ def _load_input_data( space_time_region_hash = get_space_time_region_hash(schedule.space_time_region) input_data = get_existing_download(expedition_dir, space_time_region_hash) - assert input_data is not None, ( - "Input data hasn't been found. Have you run the `virtualship fetch` command?" - ) + assert ( + input_data is not None + ), "Input data hasn't been found. Have you run the `virtualship fetch` command?" return InputData.load( directory=input_data, diff --git a/src/virtualship/expedition/schedule.py b/src/virtualship/expedition/schedule.py index 77a9a113..7b0b76e3 100644 --- a/src/virtualship/expedition/schedule.py +++ b/src/virtualship/expedition/schedule.py @@ -10,14 +10,15 @@ import pydantic import pyproj import yaml -from parcels import FieldSet from ..models.location import Location -from .ship_config import InstrumentType +from ..models.ship_config import InstrumentType from .space_time_region import SpaceTimeRegion if TYPE_CHECKING: from .input_data import InputData + from parcels import FieldSet + projection: pyproj.Geod = pyproj.Geod(ellps="WGS84") diff --git a/src/virtualship/expedition/simulate_measurements.py b/src/virtualship/expedition/simulate_measurements.py index 536d2a93..7bfd6c54 100644 --- a/src/virtualship/expedition/simulate_measurements.py +++ b/src/virtualship/expedition/simulate_measurements.py @@ -13,7 +13,7 @@ from ..instruments.drifter import simulate_drifters from ..instruments.ship_underwater_st import simulate_ship_underwater_st from ..instruments.xbt import simulate_xbt -from .ship_config import ShipConfig +from ..models.ship_config import ShipConfig from .simulate_schedule import MeasurementsToSimulate if TYPE_CHECKING: diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index 05756e78..1a0d13fd 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -15,7 +15,7 @@ from ..models.location import Location from ..models.spacetime import Spacetime from .schedule import Schedule, Waypoint -from .ship_config import InstrumentType, ShipConfig +from ..models.ship_config import InstrumentType, ShipConfig @dataclass @@ -85,9 +85,9 @@ def __init__( self._ship_config = ship_config self._schedule = schedule - assert self._schedule.waypoints[0].time is not None, ( - "First waypoint must have a time. This should have been verified before calling this function." - ) + assert ( + self._schedule.waypoints[0].time is not None + ), "First waypoint must have a time. This should have been verified before calling this function." self._time = schedule.waypoints[0].time self._location = schedule.waypoints[0].location diff --git a/src/virtualship/expedition/ship_config.py b/src/virtualship/models/ship_config.py similarity index 99% rename from src/virtualship/expedition/ship_config.py rename to src/virtualship/models/ship_config.py index c0814f5b..c0735b79 100644 --- a/src/virtualship/expedition/ship_config.py +++ b/src/virtualship/models/ship_config.py @@ -13,7 +13,7 @@ from virtualship.utils import _validate_numeric_mins_to_timedelta if TYPE_CHECKING: - from .schedule import Schedule + from ..expedition.schedule import Schedule class InstrumentType(Enum): diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index 6dbbb49c..7c8a294f 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from virtualship.expedition.schedule import Schedule - from virtualship.expedition.ship_config import ShipConfig + from virtualship.models.ship_config import ShipConfig import pandas as pd import yaml @@ -138,9 +138,8 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 4. returns the yaml information. """ - # Importing Schedule and related models from expedition module from virtualship.expedition.schedule import Location, Schedule, Waypoint - from virtualship.expedition.ship_config import InstrumentType + from virtualship.models.ship_config import InstrumentType from virtualship.expedition.space_time_region import ( SpaceTimeRegion, SpatialRange, @@ -238,7 +237,7 @@ def _get_schedule(expedition_dir: Path) -> Schedule: def _get_ship_config(expedition_dir: Path) -> ShipConfig: - from virtualship.expedition.ship_config import ShipConfig + from virtualship.models.ship_config import ShipConfig file_path = expedition_dir.joinpath(SHIP_CONFIG) try: diff --git a/tests/cli/test_fetch.py b/tests/cli/test_fetch.py index 3102ca8b..403b9a73 100644 --- a/tests/cli/test_fetch.py +++ b/tests/cli/test_fetch.py @@ -17,7 +17,7 @@ hash_to_filename, ) from virtualship.expedition.schedule import Schedule -from virtualship.expedition.ship_config import ShipConfig +from virtualship.models.ship_config import ShipConfig from virtualship.utils import get_example_config, get_example_schedule diff --git a/tests/expedition/test_ship_config.py b/tests/expedition/test_ship_config.py index 920058d2..9af5f106 100644 --- a/tests/expedition/test_ship_config.py +++ b/tests/expedition/test_ship_config.py @@ -3,7 +3,7 @@ import pytest from virtualship.expedition.schedule import Schedule -from virtualship.expedition.ship_config import ConfigError, ShipConfig +from virtualship.models.ship_config import ConfigError, ShipConfig from virtualship.utils import get_example_config, get_example_schedule expedition_dir = Path("expedition_dir") diff --git a/tests/test_mfp_to_yaml.py b/tests/test_mfp_to_yaml.py index 3ef511f5..d1e066af 100644 --- a/tests/test_mfp_to_yaml.py +++ b/tests/test_mfp_to_yaml.py @@ -4,7 +4,7 @@ import pytest from virtualship.expedition.schedule import Schedule -from virtualship.expedition.ship_config import InstrumentType +from virtualship.models.ship_config import InstrumentType from virtualship.utils import mfp_to_yaml From 9eedd314b797000b44b7448bc38a416a95983915 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:20:24 +0200 Subject: [PATCH 03/13] Move schedule to models --- src/virtualship/expedition/__init__.py | 2 +- src/virtualship/expedition/checkpoint.py | 2 +- src/virtualship/expedition/do_expedition.py | 2 +- src/virtualship/expedition/simulate_schedule.py | 2 +- src/virtualship/{expedition => models}/schedule.py | 8 ++++---- src/virtualship/models/ship_config.py | 2 +- src/virtualship/utils.py | 6 +++--- tests/cli/test_fetch.py | 2 +- tests/expedition/test_schedule.py | 2 +- tests/expedition/test_ship_config.py | 2 +- tests/test_mfp_to_yaml.py | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) rename src/virtualship/{expedition => models}/schedule.py (97%) diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 50f9229c..ae25cd5c 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, Waypoint +from ..models.schedule import Schedule, Waypoint from ..models.ship_config import ( ADCPConfig, ArgoFloatConfig, diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index 9102edf5..89a8bcfd 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -7,7 +7,7 @@ import pydantic import yaml -from .schedule import Schedule +from ..models.schedule import Schedule from ..models.ship_config import InstrumentType diff --git a/src/virtualship/expedition/do_expedition.py b/src/virtualship/expedition/do_expedition.py index 1d0b31fd..12d8094a 100644 --- a/src/virtualship/expedition/do_expedition.py +++ b/src/virtualship/expedition/do_expedition.py @@ -16,7 +16,7 @@ from .checkpoint import Checkpoint from .expedition_cost import expedition_cost from .input_data import InputData -from .schedule import Schedule +from ..models.schedule import Schedule from ..models.ship_config import ShipConfig from .simulate_measurements import simulate_measurements from .simulate_schedule import ScheduleProblem, simulate_schedule diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index 1a0d13fd..77effb01 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -14,7 +14,7 @@ from ..instruments.xbt import XBT from ..models.location import Location from ..models.spacetime import Spacetime -from .schedule import Schedule, Waypoint +from ..models.schedule import Schedule, Waypoint from ..models.ship_config import InstrumentType, ShipConfig diff --git a/src/virtualship/expedition/schedule.py b/src/virtualship/models/schedule.py similarity index 97% rename from src/virtualship/expedition/schedule.py rename to src/virtualship/models/schedule.py index 7b0b76e3..8c3e7fa1 100644 --- a/src/virtualship/expedition/schedule.py +++ b/src/virtualship/models/schedule.py @@ -11,12 +11,12 @@ import pyproj import yaml -from ..models.location import Location -from ..models.ship_config import InstrumentType -from .space_time_region import SpaceTimeRegion +from .location import Location +from .ship_config import InstrumentType +from ..expedition.space_time_region import SpaceTimeRegion if TYPE_CHECKING: - from .input_data import InputData + from ..expedition.input_data import InputData from parcels import FieldSet projection: pyproj.Geod = pyproj.Geod(ellps="WGS84") diff --git a/src/virtualship/models/ship_config.py b/src/virtualship/models/ship_config.py index c0735b79..c0814f5b 100644 --- a/src/virtualship/models/ship_config.py +++ b/src/virtualship/models/ship_config.py @@ -13,7 +13,7 @@ from virtualship.utils import _validate_numeric_mins_to_timedelta if TYPE_CHECKING: - from ..expedition.schedule import Schedule + from .schedule import Schedule class InstrumentType(Enum): diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index 7c8a294f..df3db333 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, TextIO if TYPE_CHECKING: - from virtualship.expedition.schedule import Schedule + from virtualship.models.schedule import Schedule from virtualship.models.ship_config import ShipConfig import pandas as pd @@ -138,7 +138,7 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 4. returns the yaml information. """ - from virtualship.expedition.schedule import Location, Schedule, Waypoint + from virtualship.models.schedule import Location, Schedule, Waypoint from virtualship.models.ship_config import InstrumentType from virtualship.expedition.space_time_region import ( SpaceTimeRegion, @@ -227,7 +227,7 @@ def _validate_numeric_mins_to_timedelta(value: int | float | timedelta) -> timed def _get_schedule(expedition_dir: Path) -> Schedule: """Load Schedule object from yaml config file in `expedition_dir`.""" - from virtualship.expedition.schedule import Schedule + from virtualship.models.schedule import Schedule file_path = expedition_dir.joinpath(SCHEDULE) try: diff --git a/tests/cli/test_fetch.py b/tests/cli/test_fetch.py index 403b9a73..6f813297 100644 --- a/tests/cli/test_fetch.py +++ b/tests/cli/test_fetch.py @@ -16,7 +16,7 @@ hash_model, hash_to_filename, ) -from virtualship.expedition.schedule import Schedule +from virtualship.models.schedule import Schedule from virtualship.models.ship_config import ShipConfig from virtualship.utils import get_example_config, get_example_schedule diff --git a/tests/expedition/test_schedule.py b/tests/expedition/test_schedule.py index eabcbd9a..ef8577b7 100644 --- a/tests/expedition/test_schedule.py +++ b/tests/expedition/test_schedule.py @@ -6,7 +6,7 @@ from virtualship import Location from virtualship.expedition.do_expedition import _load_input_data -from virtualship.expedition.schedule import Schedule, ScheduleError, Waypoint +from virtualship.models.schedule import Schedule, ScheduleError, Waypoint from virtualship.utils import _get_ship_config projection = pyproj.Geod(ellps="WGS84") diff --git a/tests/expedition/test_ship_config.py b/tests/expedition/test_ship_config.py index 9af5f106..e58ed8d5 100644 --- a/tests/expedition/test_ship_config.py +++ b/tests/expedition/test_ship_config.py @@ -2,7 +2,7 @@ import pytest -from virtualship.expedition.schedule import Schedule +from virtualship.models.schedule import Schedule from virtualship.models.ship_config import ConfigError, ShipConfig from virtualship.utils import get_example_config, get_example_schedule diff --git a/tests/test_mfp_to_yaml.py b/tests/test_mfp_to_yaml.py index d1e066af..9f281383 100644 --- a/tests/test_mfp_to_yaml.py +++ b/tests/test_mfp_to_yaml.py @@ -3,7 +3,7 @@ import pandas as pd import pytest -from virtualship.expedition.schedule import Schedule +from virtualship.models.schedule import Schedule from virtualship.models.ship_config import InstrumentType from virtualship.utils import mfp_to_yaml From 7ab7fc35a7aecbb7834166114e960a0d5f1cbffa Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:20:56 +0200 Subject: [PATCH 04/13] Move space_time_region to models --- src/virtualship/cli/_fetch.py | 2 +- src/virtualship/expedition/__init__.py | 2 +- src/virtualship/models/schedule.py | 2 +- src/virtualship/{expedition => models}/space_time_region.py | 0 src/virtualship/utils.py | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename src/virtualship/{expedition => models}/space_time_region.py (100%) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index c23d8d31..1ccdcb46 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -16,7 +16,7 @@ ) if TYPE_CHECKING: - from virtualship.expedition.space_time_region import SpaceTimeRegion + from virtualship.models.space_time_region import SpaceTimeRegion import click import copernicusmarine diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index ae25cd5c..9d95d580 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -12,7 +12,7 @@ ShipConfig, ShipUnderwaterSTConfig, ) -from .space_time_region import SpaceTimeRegion +from ..models.space_time_region import SpaceTimeRegion __all__ = [ "ADCPConfig", diff --git a/src/virtualship/models/schedule.py b/src/virtualship/models/schedule.py index 8c3e7fa1..bcdb23c3 100644 --- a/src/virtualship/models/schedule.py +++ b/src/virtualship/models/schedule.py @@ -13,7 +13,7 @@ from .location import Location from .ship_config import InstrumentType -from ..expedition.space_time_region import SpaceTimeRegion +from .space_time_region import SpaceTimeRegion if TYPE_CHECKING: from ..expedition.input_data import InputData diff --git a/src/virtualship/expedition/space_time_region.py b/src/virtualship/models/space_time_region.py similarity index 100% rename from src/virtualship/expedition/space_time_region.py rename to src/virtualship/models/space_time_region.py diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index df3db333..b07d5ad2 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -140,7 +140,7 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 """ from virtualship.models.schedule import Location, Schedule, Waypoint from virtualship.models.ship_config import InstrumentType - from virtualship.expedition.space_time_region import ( + from virtualship.models.space_time_region import ( SpaceTimeRegion, SpatialRange, TimeRange, From 8322aa23b9d0dd15ae5ae94b58ac19a29c35f265 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:33:40 +0200 Subject: [PATCH 05/13] Move errors to separate file --- src/virtualship/cli/_creds.py | 7 +----- src/virtualship/cli/_fetch.py | 7 +----- src/virtualship/errors.py | 28 ++++++++++++++++++++++++ src/virtualship/expedition/checkpoint.py | 7 +----- src/virtualship/models/schedule.py | 9 +++----- 5 files changed, 34 insertions(+), 24 deletions(-) create mode 100644 src/virtualship/errors.py diff --git a/src/virtualship/cli/_creds.py b/src/virtualship/cli/_creds.py index cee1c69f..34ade832 100644 --- a/src/virtualship/cli/_creds.py +++ b/src/virtualship/cli/_creds.py @@ -5,16 +5,11 @@ import click import pydantic import yaml +from virtualship.errors import CredentialFileError CREDENTIALS_FILE = "credentials.yaml" -class CredentialFileError(Exception): - """Exception raised for errors in the input file format.""" - - pass - - class Credentials(pydantic.BaseModel): """Credentials to be used in `virtualship fetch` command.""" diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 1ccdcb46..3f5ef6e2 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -14,6 +14,7 @@ _get_schedule, _get_ship_config, ) +from virtualship.errors import IncompleteDownloadError if TYPE_CHECKING: from virtualship.models.space_time_region import SpaceTimeRegion @@ -329,12 +330,6 @@ def hash_to_filename(hash: str) -> str: return f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_{hash}" -class IncompleteDownloadError(Exception): - """Exception raised for incomplete downloads.""" - - pass - - class DownloadMetadata(BaseModel): """Metadata for a data download.""" diff --git a/src/virtualship/errors.py b/src/virtualship/errors.py new file mode 100644 index 00000000..838a62a8 --- /dev/null +++ b/src/virtualship/errors.py @@ -0,0 +1,28 @@ +class CredentialFileError(Exception): + """Exception raised for errors in the input file format.""" + + pass + + +class IncompleteDownloadError(Exception): + """Exception raised for incomplete downloads.""" + + pass + + +class CheckpointError(RuntimeError): + """An error in the checkpoint.""" + + pass + + +class ScheduleError(RuntimeError): + """An error in the schedule.""" + + pass + + +class ConfigError(RuntimeError): + """An error in the config.""" + + pass diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index 89a8bcfd..ba1fe46e 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -9,6 +9,7 @@ from ..models.schedule import Schedule from ..models.ship_config import InstrumentType +from virtualship.errors import CheckpointError class _YamlDumper(yaml.SafeDumper): @@ -71,9 +72,3 @@ def verify(self, schedule: Schedule) -> None: raise CheckpointError( "Past waypoints in schedule have been changed! Restore past schedule and only change future waypoints." ) - - -class CheckpointError(RuntimeError): - """An error in the checkpoint.""" - - pass diff --git a/src/virtualship/models/schedule.py b/src/virtualship/models/schedule.py index bcdb23c3..aaefbcd7 100644 --- a/src/virtualship/models/schedule.py +++ b/src/virtualship/models/schedule.py @@ -10,6 +10,9 @@ import pydantic import pyproj import yaml +from virtualship.errors import ScheduleError +from virtualship.errors import ConfigError + from .location import Location from .ship_config import InstrumentType @@ -213,12 +216,6 @@ def verify( time = wp_next.time -class ScheduleError(RuntimeError): - """An error in the schedule.""" - - pass - - def _is_on_land_zero_uv(fieldset: FieldSet, waypoint: Waypoint) -> bool: """ Check if waypoint is on land by assuming zero velocity means land. From a33960717d199f6aae23d45380d5ff3fdeae3f5e Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:34:17 +0200 Subject: [PATCH 06/13] Run hooks --- src/virtualship/cli/_creds.py | 1 + src/virtualship/cli/_fetch.py | 2 +- src/virtualship/expedition/__init__.py | 4 ++-- src/virtualship/expedition/checkpoint.py | 3 ++- src/virtualship/expedition/do_expedition.py | 16 ++++++++-------- src/virtualship/expedition/simulate_schedule.py | 8 ++++---- src/virtualship/models/schedule.py | 6 +++--- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/virtualship/cli/_creds.py b/src/virtualship/cli/_creds.py index 34ade832..9f1d2435 100644 --- a/src/virtualship/cli/_creds.py +++ b/src/virtualship/cli/_creds.py @@ -5,6 +5,7 @@ import click import pydantic import yaml + from virtualship.errors import CredentialFileError CREDENTIALS_FILE = "credentials.yaml" diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 3f5ef6e2..4948df24 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -8,13 +8,13 @@ from pydantic import BaseModel +from virtualship.errors import IncompleteDownloadError from virtualship.utils import ( _dump_yaml, _generic_load_yaml, _get_schedule, _get_ship_config, ) -from virtualship.errors import IncompleteDownloadError if TYPE_CHECKING: from virtualship.models.space_time_region import SpaceTimeRegion diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 9d95d580..391f3401 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -1,7 +1,5 @@ """Everything for simulating an expedition.""" -from .do_expedition import do_expedition -from .input_data import InputData from ..models.schedule import Schedule, Waypoint from ..models.ship_config import ( ADCPConfig, @@ -13,6 +11,8 @@ ShipUnderwaterSTConfig, ) from ..models.space_time_region import SpaceTimeRegion +from .do_expedition import do_expedition +from .input_data import InputData __all__ = [ "ADCPConfig", diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index ba1fe46e..0a72387e 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -7,9 +7,10 @@ import pydantic import yaml +from virtualship.errors import CheckpointError + from ..models.schedule import Schedule from ..models.ship_config import InstrumentType -from virtualship.errors import CheckpointError class _YamlDumper(yaml.SafeDumper): diff --git a/src/virtualship/expedition/do_expedition.py b/src/virtualship/expedition/do_expedition.py index 12d8094a..10d7f9e0 100644 --- a/src/virtualship/expedition/do_expedition.py +++ b/src/virtualship/expedition/do_expedition.py @@ -13,11 +13,11 @@ _get_ship_config, ) +from ..models.schedule import Schedule +from ..models.ship_config import ShipConfig from .checkpoint import Checkpoint from .expedition_cost import expedition_cost from .input_data import InputData -from ..models.schedule import Schedule -from ..models.ship_config import ShipConfig from .simulate_measurements import simulate_measurements from .simulate_schedule import ScheduleProblem, simulate_schedule @@ -84,9 +84,9 @@ def do_expedition(expedition_dir: str | Path, input_data: Path | None = None) -> os.makedirs(expedition_dir.joinpath("results")) # calculate expedition cost in US$ - assert ( - schedule.waypoints[0].time is not None - ), "First waypoint has no time. This should not be possible as it should have been verified before." + assert schedule.waypoints[0].time is not None, ( + "First waypoint has no time. This should not be possible as it should have been verified before." + ) time_past = schedule_results.time - schedule.waypoints[0].time cost = expedition_cost(schedule_results, time_past) with open(expedition_dir.joinpath("results", "cost.txt"), "w") as file: @@ -131,9 +131,9 @@ def _load_input_data( space_time_region_hash = get_space_time_region_hash(schedule.space_time_region) input_data = get_existing_download(expedition_dir, space_time_region_hash) - assert ( - input_data is not None - ), "Input data hasn't been found. Have you run the `virtualship fetch` command?" + assert input_data is not None, ( + "Input data hasn't been found. Have you run the `virtualship fetch` command?" + ) return InputData.load( directory=input_data, diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index 77effb01..3f075a78 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -13,9 +13,9 @@ from ..instruments.drifter import Drifter from ..instruments.xbt import XBT from ..models.location import Location -from ..models.spacetime import Spacetime from ..models.schedule import Schedule, Waypoint from ..models.ship_config import InstrumentType, ShipConfig +from ..models.spacetime import Spacetime @dataclass @@ -85,9 +85,9 @@ def __init__( self._ship_config = ship_config self._schedule = schedule - assert ( - self._schedule.waypoints[0].time is not None - ), "First waypoint must have a time. This should have been verified before calling this function." + assert self._schedule.waypoints[0].time is not None, ( + "First waypoint must have a time. This should have been verified before calling this function." + ) self._time = schedule.waypoints[0].time self._location = schedule.waypoints[0].location diff --git a/src/virtualship/models/schedule.py b/src/virtualship/models/schedule.py index aaefbcd7..4fb3f23c 100644 --- a/src/virtualship/models/schedule.py +++ b/src/virtualship/models/schedule.py @@ -10,18 +10,18 @@ import pydantic import pyproj import yaml -from virtualship.errors import ScheduleError -from virtualship.errors import ConfigError +from virtualship.errors import ScheduleError from .location import Location from .ship_config import InstrumentType from .space_time_region import SpaceTimeRegion if TYPE_CHECKING: - from ..expedition.input_data import InputData from parcels import FieldSet + from ..expedition.input_data import InputData + projection: pyproj.Geod = pyproj.Geod(ellps="WGS84") From 1ecd2010a21dd149411008e37ced816b5ed5298b Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 17:35:22 +0200 Subject: [PATCH 07/13] Update reference to ConfigError --- src/virtualship/models/ship_config.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/virtualship/models/ship_config.py b/src/virtualship/models/ship_config.py index c0814f5b..be3ee30d 100644 --- a/src/virtualship/models/ship_config.py +++ b/src/virtualship/models/ship_config.py @@ -10,6 +10,7 @@ import pydantic import yaml +from virtualship.errors import ConfigError from virtualship.utils import _validate_numeric_mins_to_timedelta if TYPE_CHECKING: @@ -317,9 +318,3 @@ def verify(self, schedule: Schedule) -> None: raise ConfigError( "Planning has a waypoint with XBT instrument, but configuration does not configure XBT." ) - - -class ConfigError(RuntimeError): - """An error in the config.""" - - pass From 1e48d558762d95c940543dd3598cc6dd109ec4da Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 18:04:37 +0200 Subject: [PATCH 08/13] Add tidy-imports ruff rule --- pyproject.toml | 1 + src/virtualship/expedition/__init__.py | 7 ++++--- src/virtualship/expedition/checkpoint.py | 5 ++--- src/virtualship/expedition/do_expedition.py | 4 ++-- .../expedition/simulate_measurements.py | 17 +++++++++-------- .../expedition/simulate_schedule.py | 18 +++++++++--------- src/virtualship/instruments/adcp.py | 2 +- src/virtualship/instruments/argo_float.py | 2 +- src/virtualship/instruments/ctd.py | 2 +- src/virtualship/instruments/ctd_bgc.py | 2 +- src/virtualship/instruments/drifter.py | 2 +- .../instruments/ship_underwater_st.py | 2 +- src/virtualship/instruments/xbt.py | 2 +- src/virtualship/models/schedule.py | 2 +- 14 files changed, 35 insertions(+), 33 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c15a19cd..34431572 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,6 +95,7 @@ select = [ "ICN", # import conventions "RUF", # ruff "ISC001", # single-line-implicit-string-concatenation + "TID", # flake8-tidy-imports ] ignore = [ # line too long (82 > 79 characters) diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 391f3401..ea0bfe43 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -1,7 +1,7 @@ """Everything for simulating an expedition.""" -from ..models.schedule import Schedule, Waypoint -from ..models.ship_config import ( +from virtualship.models.schedule import Schedule, Waypoint +from virtualship.models.ship_config import ( ADCPConfig, ArgoFloatConfig, CTD_BGCConfig, @@ -10,7 +10,8 @@ ShipConfig, ShipUnderwaterSTConfig, ) -from ..models.space_time_region import SpaceTimeRegion +from virtualship.models.space_time_region import SpaceTimeRegion + from .do_expedition import do_expedition from .input_data import InputData diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index 0a72387e..735c4b71 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -8,9 +8,8 @@ import yaml from virtualship.errors import CheckpointError - -from ..models.schedule import Schedule -from ..models.ship_config import InstrumentType +from virtualship.models.schedule import Schedule +from virtualship.models.ship_config import InstrumentType class _YamlDumper(yaml.SafeDumper): diff --git a/src/virtualship/expedition/do_expedition.py b/src/virtualship/expedition/do_expedition.py index 10d7f9e0..a1ca2d85 100644 --- a/src/virtualship/expedition/do_expedition.py +++ b/src/virtualship/expedition/do_expedition.py @@ -7,14 +7,14 @@ import pyproj from virtualship.cli._fetch import get_existing_download, get_space_time_region_hash +from virtualship.models.schedule import Schedule +from virtualship.models.ship_config import ShipConfig from virtualship.utils import ( CHECKPOINT, _get_schedule, _get_ship_config, ) -from ..models.schedule import Schedule -from ..models.ship_config import ShipConfig from .checkpoint import Checkpoint from .expedition_cost import expedition_cost from .input_data import InputData diff --git a/src/virtualship/expedition/simulate_measurements.py b/src/virtualship/expedition/simulate_measurements.py index 7bfd6c54..3a44f5ab 100644 --- a/src/virtualship/expedition/simulate_measurements.py +++ b/src/virtualship/expedition/simulate_measurements.py @@ -6,14 +6,15 @@ from pathlib import Path from typing import TYPE_CHECKING -from ..instruments.adcp import simulate_adcp -from ..instruments.argo_float import simulate_argo_floats -from ..instruments.ctd import simulate_ctd -from ..instruments.ctd_bgc import simulate_ctd_bgc -from ..instruments.drifter import simulate_drifters -from ..instruments.ship_underwater_st import simulate_ship_underwater_st -from ..instruments.xbt import simulate_xbt -from ..models.ship_config import ShipConfig +from virtualship.instruments.adcp import simulate_adcp +from virtualship.instruments.argo_float import simulate_argo_floats +from virtualship.instruments.ctd import simulate_ctd +from virtualship.instruments.ctd_bgc import simulate_ctd_bgc +from virtualship.instruments.drifter import simulate_drifters +from virtualship.instruments.ship_underwater_st import simulate_ship_underwater_st +from virtualship.instruments.xbt import simulate_xbt +from virtualship.models.ship_config import ShipConfig + from .simulate_schedule import MeasurementsToSimulate if TYPE_CHECKING: diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index 3f075a78..ffdad521 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -7,15 +7,15 @@ import pyproj -from ..instruments.argo_float import ArgoFloat -from ..instruments.ctd import CTD -from ..instruments.ctd_bgc import CTD_BGC -from ..instruments.drifter import Drifter -from ..instruments.xbt import XBT -from ..models.location import Location -from ..models.schedule import Schedule, Waypoint -from ..models.ship_config import InstrumentType, ShipConfig -from ..models.spacetime import Spacetime +from virtualship.instruments.argo_float import ArgoFloat +from virtualship.instruments.ctd import CTD +from virtualship.instruments.ctd_bgc import CTD_BGC +from virtualship.instruments.drifter import Drifter +from virtualship.instruments.xbt import XBT +from virtualship.models.location import Location +from virtualship.models.schedule import Schedule, Waypoint +from virtualship.models.ship_config import InstrumentType, ShipConfig +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/adcp.py b/src/virtualship/instruments/adcp.py index 44cb1518..44e3460a 100644 --- a/src/virtualship/instruments/adcp.py +++ b/src/virtualship/instruments/adcp.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/argo_float.py b/src/virtualship/instruments/argo_float.py index 816d59b5..66522f27 100644 --- a/src/virtualship/instruments/argo_float.py +++ b/src/virtualship/instruments/argo_float.py @@ -15,7 +15,7 @@ Variable, ) -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd.py b/src/virtualship/instruments/ctd.py index 1ecc5a16..51450339 100644 --- a/src/virtualship/instruments/ctd.py +++ b/src/virtualship/instruments/ctd.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd_bgc.py b/src/virtualship/instruments/ctd_bgc.py index 955a3ed5..93c07d72 100644 --- a/src/virtualship/instruments/ctd_bgc.py +++ b/src/virtualship/instruments/ctd_bgc.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/drifter.py b/src/virtualship/instruments/drifter.py index d2c3c099..5fcd1d5d 100644 --- a/src/virtualship/instruments/drifter.py +++ b/src/virtualship/instruments/drifter.py @@ -7,7 +7,7 @@ import numpy as np from parcels import AdvectionRK4, FieldSet, JITParticle, ParticleSet, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/instruments/ship_underwater_st.py b/src/virtualship/instruments/ship_underwater_st.py index ada68ad7..2e015454 100644 --- a/src/virtualship/instruments/ship_underwater_st.py +++ b/src/virtualship/instruments/ship_underwater_st.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/xbt.py b/src/virtualship/instruments/xbt.py index ecd66ea5..07549857 100644 --- a/src/virtualship/instruments/xbt.py +++ b/src/virtualship/instruments/xbt.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from ..models.spacetime import Spacetime +from virtualship.models.spacetime import Spacetime @dataclass diff --git a/src/virtualship/models/schedule.py b/src/virtualship/models/schedule.py index 4fb3f23c..c29cd4c9 100644 --- a/src/virtualship/models/schedule.py +++ b/src/virtualship/models/schedule.py @@ -20,7 +20,7 @@ if TYPE_CHECKING: from parcels import FieldSet - from ..expedition.input_data import InputData + from virtualship.expedition.input_data import InputData projection: pyproj.Geod = pyproj.Geod(ellps="WGS84") From 6a632a543e5ade01f740d6bb5a65f4f055a8409b Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 18:09:41 +0200 Subject: [PATCH 09/13] Add models.__init__ --- src/virtualship/models/__init__.py | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/virtualship/models/__init__.py diff --git a/src/virtualship/models/__init__.py b/src/virtualship/models/__init__.py new file mode 100644 index 00000000..68a65d08 --- /dev/null +++ b/src/virtualship/models/__init__.py @@ -0,0 +1,42 @@ +"""Pydantic models and data classes used to configure virtualship.""" + +from .location import Location +from .schedule import Schedule, Waypoint +from .ship_config import ( + ADCPConfig, + ArgoFloatConfig, + CTD_BGCConfig, + CTDConfig, + DrifterConfig, + InstrumentType, + ShipConfig, + ShipUnderwaterSTConfig, + XBTConfig, +) +from .space_time_region import ( + SpaceTimeRegion, + SpatialRange, + TimeRange, +) +from .spacetime import ( + Spacetime, +) + +__all__ = [ # noqa: RUF022 + "Location", + "Schedule", + "Waypoint", + "InstrumentType", + "ArgoFloatConfig", + "ADCPConfig", + "CTDConfig", + "CTD_BGCConfig", + "ShipUnderwaterSTConfig", + "DrifterConfig", + "XBTConfig", + "ShipConfig", + "SpatialRange", + "TimeRange", + "SpaceTimeRegion", + "Spacetime", +] From db140ca120ba3a9e9fe889e8678950e23cfed115 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 18:13:23 +0200 Subject: [PATCH 10/13] Update imports to models subpackage --- src/virtualship/cli/_fetch.py | 4 ++-- src/virtualship/expedition/__init__.py | 7 ++++--- src/virtualship/expedition/checkpoint.py | 3 +-- src/virtualship/expedition/do_expedition.py | 3 +-- .../expedition/simulate_measurements.py | 2 +- src/virtualship/expedition/simulate_schedule.py | 12 ++++++++---- src/virtualship/instruments/adcp.py | 2 +- src/virtualship/instruments/argo_float.py | 2 +- src/virtualship/instruments/ctd.py | 2 +- src/virtualship/instruments/ctd_bgc.py | 2 +- src/virtualship/instruments/drifter.py | 2 +- src/virtualship/instruments/ship_underwater_st.py | 2 +- src/virtualship/instruments/xbt.py | 2 +- src/virtualship/utils.py | 15 ++++++++------- tests/cli/test_fetch.py | 3 +-- tests/expedition/test_schedule.py | 2 +- tests/expedition/test_ship_config.py | 3 +-- tests/test_mfp_to_yaml.py | 3 +-- 18 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 4948df24..df66cd66 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -17,7 +17,7 @@ ) if TYPE_CHECKING: - from virtualship.models.space_time_region import SpaceTimeRegion + from virtualship.models import SpaceTimeRegion import click import copernicusmarine @@ -39,7 +39,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.models.ship_config import InstrumentType + from virtualship.models 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 ea0bfe43..428b9d7e 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -1,16 +1,17 @@ """Everything for simulating an expedition.""" -from virtualship.models.schedule import Schedule, Waypoint -from virtualship.models.ship_config import ( +from virtualship.models import ( ADCPConfig, ArgoFloatConfig, CTD_BGCConfig, CTDConfig, DrifterConfig, + Schedule, ShipConfig, ShipUnderwaterSTConfig, + SpaceTimeRegion, + Waypoint, ) -from virtualship.models.space_time_region import SpaceTimeRegion from .do_expedition import do_expedition from .input_data import InputData diff --git a/src/virtualship/expedition/checkpoint.py b/src/virtualship/expedition/checkpoint.py index 735c4b71..6daf1a9b 100644 --- a/src/virtualship/expedition/checkpoint.py +++ b/src/virtualship/expedition/checkpoint.py @@ -8,8 +8,7 @@ import yaml from virtualship.errors import CheckpointError -from virtualship.models.schedule import Schedule -from virtualship.models.ship_config import InstrumentType +from virtualship.models import InstrumentType, Schedule class _YamlDumper(yaml.SafeDumper): diff --git a/src/virtualship/expedition/do_expedition.py b/src/virtualship/expedition/do_expedition.py index a1ca2d85..84150de8 100644 --- a/src/virtualship/expedition/do_expedition.py +++ b/src/virtualship/expedition/do_expedition.py @@ -7,8 +7,7 @@ import pyproj from virtualship.cli._fetch import get_existing_download, get_space_time_region_hash -from virtualship.models.schedule import Schedule -from virtualship.models.ship_config import ShipConfig +from virtualship.models import Schedule, ShipConfig from virtualship.utils import ( CHECKPOINT, _get_schedule, diff --git a/src/virtualship/expedition/simulate_measurements.py b/src/virtualship/expedition/simulate_measurements.py index 3a44f5ab..31610332 100644 --- a/src/virtualship/expedition/simulate_measurements.py +++ b/src/virtualship/expedition/simulate_measurements.py @@ -13,7 +13,7 @@ from virtualship.instruments.drifter import simulate_drifters from virtualship.instruments.ship_underwater_st import simulate_ship_underwater_st from virtualship.instruments.xbt import simulate_xbt -from virtualship.models.ship_config import ShipConfig +from virtualship.models import ShipConfig from .simulate_schedule import MeasurementsToSimulate diff --git a/src/virtualship/expedition/simulate_schedule.py b/src/virtualship/expedition/simulate_schedule.py index ffdad521..95fa2f5f 100644 --- a/src/virtualship/expedition/simulate_schedule.py +++ b/src/virtualship/expedition/simulate_schedule.py @@ -12,10 +12,14 @@ from virtualship.instruments.ctd_bgc import CTD_BGC from virtualship.instruments.drifter import Drifter from virtualship.instruments.xbt import XBT -from virtualship.models.location import Location -from virtualship.models.schedule import Schedule, Waypoint -from virtualship.models.ship_config import InstrumentType, ShipConfig -from virtualship.models.spacetime import Spacetime +from virtualship.models import ( + InstrumentType, + Location, + Schedule, + ShipConfig, + Spacetime, + Waypoint, +) @dataclass diff --git a/src/virtualship/instruments/adcp.py b/src/virtualship/instruments/adcp.py index 44e3460a..af2c285e 100644 --- a/src/virtualship/instruments/adcp.py +++ b/src/virtualship/instruments/adcp.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/argo_float.py b/src/virtualship/instruments/argo_float.py index 66522f27..d0976367 100644 --- a/src/virtualship/instruments/argo_float.py +++ b/src/virtualship/instruments/argo_float.py @@ -15,7 +15,7 @@ Variable, ) -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd.py b/src/virtualship/instruments/ctd.py index 51450339..41185007 100644 --- a/src/virtualship/instruments/ctd.py +++ b/src/virtualship/instruments/ctd.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime @dataclass diff --git a/src/virtualship/instruments/ctd_bgc.py b/src/virtualship/instruments/ctd_bgc.py index 93c07d72..acd4df61 100644 --- a/src/virtualship/instruments/ctd_bgc.py +++ b/src/virtualship/instruments/ctd_bgc.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime @dataclass diff --git a/src/virtualship/instruments/drifter.py b/src/virtualship/instruments/drifter.py index 5fcd1d5d..5aef240f 100644 --- a/src/virtualship/instruments/drifter.py +++ b/src/virtualship/instruments/drifter.py @@ -7,7 +7,7 @@ import numpy as np from parcels import AdvectionRK4, FieldSet, JITParticle, ParticleSet, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime @dataclass diff --git a/src/virtualship/instruments/ship_underwater_st.py b/src/virtualship/instruments/ship_underwater_st.py index 2e015454..7b08ad4b 100644 --- a/src/virtualship/instruments/ship_underwater_st.py +++ b/src/virtualship/instruments/ship_underwater_st.py @@ -5,7 +5,7 @@ import numpy as np from parcels import FieldSet, ParticleSet, ScipyParticle, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime # we specifically use ScipyParticle because we have many small calls to execute # there is some overhead with JITParticle and this ends up being significantly faster diff --git a/src/virtualship/instruments/xbt.py b/src/virtualship/instruments/xbt.py index 07549857..6d75be8c 100644 --- a/src/virtualship/instruments/xbt.py +++ b/src/virtualship/instruments/xbt.py @@ -7,7 +7,7 @@ import numpy as np from parcels import FieldSet, JITParticle, ParticleSet, Variable -from virtualship.models.spacetime import Spacetime +from virtualship.models import Spacetime @dataclass diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index b07d5ad2..c494df96 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -9,8 +9,7 @@ from typing import TYPE_CHECKING, TextIO if TYPE_CHECKING: - from virtualship.models.schedule import Schedule - from virtualship.models.ship_config import ShipConfig + from virtualship.models import Schedule, ShipConfig import pandas as pd import yaml @@ -138,12 +137,14 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 4. returns the yaml information. """ - from virtualship.models.schedule import Location, Schedule, Waypoint - from virtualship.models.ship_config import InstrumentType - from virtualship.models.space_time_region import ( + from virtualship.models import ( + InstrumentType, + Location, + Schedule, SpaceTimeRegion, SpatialRange, TimeRange, + Waypoint, ) # Read data from file @@ -227,7 +228,7 @@ def _validate_numeric_mins_to_timedelta(value: int | float | timedelta) -> timed def _get_schedule(expedition_dir: Path) -> Schedule: """Load Schedule object from yaml config file in `expedition_dir`.""" - from virtualship.models.schedule import Schedule + from virtualship.models import Schedule file_path = expedition_dir.joinpath(SCHEDULE) try: @@ -237,7 +238,7 @@ def _get_schedule(expedition_dir: Path) -> Schedule: def _get_ship_config(expedition_dir: Path) -> ShipConfig: - from virtualship.models.ship_config import ShipConfig + from virtualship.models import ShipConfig file_path = expedition_dir.joinpath(SHIP_CONFIG) try: diff --git a/tests/cli/test_fetch.py b/tests/cli/test_fetch.py index 6f813297..856b72f6 100644 --- a/tests/cli/test_fetch.py +++ b/tests/cli/test_fetch.py @@ -16,8 +16,7 @@ hash_model, hash_to_filename, ) -from virtualship.models.schedule import Schedule -from virtualship.models.ship_config import ShipConfig +from virtualship.models import Schedule, ShipConfig from virtualship.utils import get_example_config, get_example_schedule diff --git a/tests/expedition/test_schedule.py b/tests/expedition/test_schedule.py index ef8577b7..b83253b6 100644 --- a/tests/expedition/test_schedule.py +++ b/tests/expedition/test_schedule.py @@ -6,7 +6,7 @@ from virtualship import Location from virtualship.expedition.do_expedition import _load_input_data -from virtualship.models.schedule import Schedule, ScheduleError, Waypoint +from virtualship.models import Schedule, ScheduleError, Waypoint from virtualship.utils import _get_ship_config projection = pyproj.Geod(ellps="WGS84") diff --git a/tests/expedition/test_ship_config.py b/tests/expedition/test_ship_config.py index e58ed8d5..5abdf929 100644 --- a/tests/expedition/test_ship_config.py +++ b/tests/expedition/test_ship_config.py @@ -2,8 +2,7 @@ import pytest -from virtualship.models.schedule import Schedule -from virtualship.models.ship_config import ConfigError, ShipConfig +from virtualship.models import ConfigError, Schedule, ShipConfig from virtualship.utils import get_example_config, get_example_schedule expedition_dir = Path("expedition_dir") diff --git a/tests/test_mfp_to_yaml.py b/tests/test_mfp_to_yaml.py index 9f281383..e230d2db 100644 --- a/tests/test_mfp_to_yaml.py +++ b/tests/test_mfp_to_yaml.py @@ -3,8 +3,7 @@ import pandas as pd import pytest -from virtualship.models.schedule import Schedule -from virtualship.models.ship_config import InstrumentType +from virtualship.models import InstrumentType, Schedule from virtualship.utils import mfp_to_yaml From 5b38efc9ed5029b90afde7cc20a61a2be96a762a Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Wed, 21 May 2025 18:14:59 +0200 Subject: [PATCH 11/13] Update imports of errors --- tests/expedition/test_schedule.py | 3 ++- tests/expedition/test_ship_config.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/expedition/test_schedule.py b/tests/expedition/test_schedule.py index b83253b6..ff4d4893 100644 --- a/tests/expedition/test_schedule.py +++ b/tests/expedition/test_schedule.py @@ -5,8 +5,9 @@ import pytest from virtualship import Location +from virtualship.errors import ScheduleError from virtualship.expedition.do_expedition import _load_input_data -from virtualship.models import Schedule, ScheduleError, Waypoint +from virtualship.models import Schedule, Waypoint from virtualship.utils import _get_ship_config projection = pyproj.Geod(ellps="WGS84") diff --git a/tests/expedition/test_ship_config.py b/tests/expedition/test_ship_config.py index 5abdf929..6444e985 100644 --- a/tests/expedition/test_ship_config.py +++ b/tests/expedition/test_ship_config.py @@ -2,7 +2,8 @@ import pytest -from virtualship.models import ConfigError, Schedule, ShipConfig +from virtualship.errors import ConfigError +from virtualship.models import Schedule, ShipConfig from virtualship.utils import get_example_config, get_example_schedule expedition_dir = Path("expedition_dir") From a87e9ccaa6e4bdeaf8ac5649af4ca44f63868d97 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Thu, 22 May 2025 10:14:47 +0200 Subject: [PATCH 12/13] cleanup virtualship/expedition/__init__.py --- src/virtualship/expedition/__init__.py | 25 ---------------------- tests/expedition/test_simulate_schedule.py | 2 +- tests/test_utils.py | 2 +- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/src/virtualship/expedition/__init__.py b/src/virtualship/expedition/__init__.py index 428b9d7e..43d24844 100644 --- a/src/virtualship/expedition/__init__.py +++ b/src/virtualship/expedition/__init__.py @@ -1,34 +1,9 @@ """Everything for simulating an expedition.""" -from virtualship.models import ( - ADCPConfig, - ArgoFloatConfig, - CTD_BGCConfig, - CTDConfig, - DrifterConfig, - Schedule, - ShipConfig, - ShipUnderwaterSTConfig, - SpaceTimeRegion, - Waypoint, -) - from .do_expedition import do_expedition from .input_data import InputData __all__ = [ - "ADCPConfig", - "ArgoFloatConfig", - "CTDConfig", - "CTD_BGCConfig", - "DrifterConfig", "InputData", - "InstrumentType", - "Schedule", - "ShipConfig", - "ShipUnderwaterSTConfig", - "SpaceTimeRegion", - "Waypoint", "do_expedition", - "instruments", ] diff --git a/tests/expedition/test_simulate_schedule.py b/tests/expedition/test_simulate_schedule.py index 8c42097b..82a494ca 100644 --- a/tests/expedition/test_simulate_schedule.py +++ b/tests/expedition/test_simulate_schedule.py @@ -3,12 +3,12 @@ import pyproj from virtualship import Location -from virtualship.expedition import Schedule, ShipConfig, Waypoint from virtualship.expedition.simulate_schedule import ( ScheduleOk, ScheduleProblem, simulate_schedule, ) +from virtualship.models import Schedule, ShipConfig, Waypoint def test_simulate_schedule_feasible() -> None: diff --git a/tests/test_utils.py b/tests/test_utils.py index b0d00be9..4c6db8fc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,4 +1,4 @@ -from virtualship.expedition import Schedule, ShipConfig +from virtualship.models import Schedule, ShipConfig from virtualship.utils import get_example_config, get_example_schedule From 54ec9855b4524b135835abd6397b58a30d68a629 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Thu, 22 May 2025 10:26:57 +0200 Subject: [PATCH 13/13] cleanup virtualship/__init__.py --- docs/user-guide/tutorials/Drifter_data_tutorial.ipynb | 2 +- src/virtualship/__init__.py | 5 ----- src/virtualship/models/__init__.py | 2 +- tests/expedition/test_schedule.py | 3 +-- tests/expedition/test_simulate_schedule.py | 3 +-- tests/instruments/test_adcp.py | 2 +- tests/instruments/test_argo_float.py | 2 +- tests/instruments/test_ctd.py | 2 +- tests/instruments/test_ctd_bgc.py | 2 +- tests/instruments/test_drifter.py | 2 +- tests/instruments/test_ship_underwater_st.py | 2 +- tests/instruments/test_xbt.py | 2 +- 12 files changed, 11 insertions(+), 18 deletions(-) diff --git a/docs/user-guide/tutorials/Drifter_data_tutorial.ipynb b/docs/user-guide/tutorials/Drifter_data_tutorial.ipynb index 41c62bfa..c2d9424a 100755 --- a/docs/user-guide/tutorials/Drifter_data_tutorial.ipynb +++ b/docs/user-guide/tutorials/Drifter_data_tutorial.ipynb @@ -17,7 +17,7 @@ "metadata": {}, "outputs": [], "source": [ - "from virtualship import Location, Spacetime\n", + "from virtualship.models import Location, Spacetime\n", "from virtualship.instruments.drifter import Drifter, simulate_drifters\n", "from virtualship.expedition.input_data import InputData\n", "from pathlib import Path\n", diff --git a/src/virtualship/__init__.py b/src/virtualship/__init__.py index 755e03de..596b9c2c 100644 --- a/src/virtualship/__init__.py +++ b/src/virtualship/__init__.py @@ -2,9 +2,6 @@ from importlib.metadata import version as _version -from .models.location import Location -from .models.spacetime import Spacetime - try: __version__ = _version("virtualship") except Exception: @@ -12,7 +9,5 @@ __version__ = "unknown" __all__ = [ - "Location", - "Spacetime", "__version__", ] diff --git a/src/virtualship/models/__init__.py b/src/virtualship/models/__init__.py index 68a65d08..48106056 100644 --- a/src/virtualship/models/__init__.py +++ b/src/virtualship/models/__init__.py @@ -1,4 +1,4 @@ -"""Pydantic models and data classes used to configure virtualship.""" +"""Pydantic models and data classes used to configure virtualship (i.e., in the configuration files or settings).""" from .location import Location from .schedule import Schedule, Waypoint diff --git a/tests/expedition/test_schedule.py b/tests/expedition/test_schedule.py index ff4d4893..d45900e0 100644 --- a/tests/expedition/test_schedule.py +++ b/tests/expedition/test_schedule.py @@ -4,10 +4,9 @@ import pyproj import pytest -from virtualship import Location from virtualship.errors import ScheduleError from virtualship.expedition.do_expedition import _load_input_data -from virtualship.models import Schedule, Waypoint +from virtualship.models import Location, Schedule, Waypoint from virtualship.utils import _get_ship_config projection = pyproj.Geod(ellps="WGS84") diff --git a/tests/expedition/test_simulate_schedule.py b/tests/expedition/test_simulate_schedule.py index 82a494ca..9eecd73d 100644 --- a/tests/expedition/test_simulate_schedule.py +++ b/tests/expedition/test_simulate_schedule.py @@ -2,13 +2,12 @@ import pyproj -from virtualship import Location from virtualship.expedition.simulate_schedule import ( ScheduleOk, ScheduleProblem, simulate_schedule, ) -from virtualship.models import Schedule, ShipConfig, Waypoint +from virtualship.models import Location, Schedule, ShipConfig, Waypoint def test_simulate_schedule_feasible() -> None: diff --git a/tests/instruments/test_adcp.py b/tests/instruments/test_adcp.py index f32014c8..569f15a1 100644 --- a/tests/instruments/test_adcp.py +++ b/tests/instruments/test_adcp.py @@ -6,8 +6,8 @@ import xarray as xr from parcels import FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.adcp import simulate_adcp +from virtualship.models import Location, Spacetime def test_simulate_adcp(tmpdir) -> None: diff --git a/tests/instruments/test_argo_float.py b/tests/instruments/test_argo_float.py index 31aafe53..3eda53ae 100644 --- a/tests/instruments/test_argo_float.py +++ b/tests/instruments/test_argo_float.py @@ -6,8 +6,8 @@ import xarray as xr from parcels import FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.argo_float import ArgoFloat, simulate_argo_floats +from virtualship.models import Location, Spacetime def test_simulate_argo_floats(tmpdir) -> None: diff --git a/tests/instruments/test_ctd.py b/tests/instruments/test_ctd.py index f1fc26a6..14e0a276 100644 --- a/tests/instruments/test_ctd.py +++ b/tests/instruments/test_ctd.py @@ -11,8 +11,8 @@ import xarray as xr from parcels import Field, FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.ctd import CTD, simulate_ctd +from virtualship.models import Location, Spacetime def test_simulate_ctds(tmpdir) -> None: diff --git a/tests/instruments/test_ctd_bgc.py b/tests/instruments/test_ctd_bgc.py index 8083c580..f26e34b1 100644 --- a/tests/instruments/test_ctd_bgc.py +++ b/tests/instruments/test_ctd_bgc.py @@ -11,8 +11,8 @@ import xarray as xr from parcels import Field, FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.ctd_bgc import CTD_BGC, simulate_ctd_bgc +from virtualship.models import Location, Spacetime def test_simulate_ctd_bgcs(tmpdir) -> None: diff --git a/tests/instruments/test_drifter.py b/tests/instruments/test_drifter.py index c62b5d60..ae230a87 100644 --- a/tests/instruments/test_drifter.py +++ b/tests/instruments/test_drifter.py @@ -6,8 +6,8 @@ import xarray as xr from parcels import FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.drifter import Drifter, simulate_drifters +from virtualship.models import Location, Spacetime def test_simulate_drifters(tmpdir) -> None: diff --git a/tests/instruments/test_ship_underwater_st.py b/tests/instruments/test_ship_underwater_st.py index 210e7340..9d44ee6d 100644 --- a/tests/instruments/test_ship_underwater_st.py +++ b/tests/instruments/test_ship_underwater_st.py @@ -6,8 +6,8 @@ import xarray as xr from parcels import FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.ship_underwater_st import simulate_ship_underwater_st +from virtualship.models import Location, Spacetime def test_simulate_ship_underwater_st(tmpdir) -> None: diff --git a/tests/instruments/test_xbt.py b/tests/instruments/test_xbt.py index 232e0c8b..97e33ade 100644 --- a/tests/instruments/test_xbt.py +++ b/tests/instruments/test_xbt.py @@ -11,8 +11,8 @@ import xarray as xr from parcels import Field, FieldSet -from virtualship import Location, Spacetime from virtualship.instruments.xbt import XBT, simulate_xbt +from virtualship.models import Location, Spacetime def test_simulate_xbts(tmpdir) -> None: