From 221a0edfc446b92869111ac3424458e5d1c9a15c Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Wed, 30 Apr 2025 15:13:08 +0200 Subject: [PATCH 01/10] update init command to use CTD_BGC as new instrument when making schedule --- src/virtualship/expedition/instrument_type.py | 1 + src/virtualship/utils.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/virtualship/expedition/instrument_type.py b/src/virtualship/expedition/instrument_type.py index 82360c7b..43ffe68d 100644 --- a/src/virtualship/expedition/instrument_type.py +++ b/src/virtualship/expedition/instrument_type.py @@ -7,6 +7,7 @@ class InstrumentType(Enum): """Types of instruments.""" CTD = "CTD" + CTD_BGC = "CTD_BGC" DRIFTER = "DRIFTER" ARGO_FLOAT = "ARGO_FLOAT" XBT = "XBT" diff --git a/src/virtualship/utils.py b/src/virtualship/utils.py index c798a3dd..848d5d63 100644 --- a/src/virtualship/utils.py +++ b/src/virtualship/utils.py @@ -157,6 +157,7 @@ def mfp_to_yaml(coordinates_file_path: str, yaml_output_path: str): # noqa: D41 instrument_max_depths = { "XBT": 2000, "CTD": 5000, + "CTD_BGC": 5000, "DRIFTER": 1, "ARGO_FLOAT": 2000, } From ff28801f877af66907862aa30ff51aea1f37b961 Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Thu, 1 May 2025 14:51:06 +0200 Subject: [PATCH 02/10] update example ship_config file to also include CTD_BGC instrument config --- src/virtualship/static/ship_config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/virtualship/static/ship_config.yaml b/src/virtualship/static/ship_config.yaml index 5066e38d..34d6c6ea 100644 --- a/src/virtualship/static/ship_config.yaml +++ b/src/virtualship/static/ship_config.yaml @@ -14,6 +14,10 @@ ctd_config: max_depth_meter: -2000.0 min_depth_meter: -11.0 stationkeeping_time_minutes: 20.0 +ctd_bgc_config: + max_depth_meter: -2000.0 + min_depth_meter: -11.0 + stationkeeping_time_minutes: 20.0 drifter_config: depth_meter: 0.0 lifetime_minutes: 60480.0 From 9464a17d6aac6e6a3a4297d3c16c7177d2f1096d Mon Sep 17 00:00:00 2001 From: Jamie Atkins <106238905+j-atkins@users.noreply.github.com> Date: Fri, 2 May 2025 13:28:46 +0200 Subject: [PATCH 03/10] Prevent fetch from downloading unnecessary data and skipping data download for certain instruments (#175) * fixes for over-extensive data downloads and skipping certain instruments * fixes based on PR feedback #175 --- src/virtualship/cli/_fetch.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 340edfd9..16712d38 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -38,6 +38,8 @@ 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 + if sum([username is None, password is None]) == 1: raise ValueError("Both username and password must be provided when using CLI.") @@ -88,10 +90,10 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None {"XBT", "CTD", "SHIP_UNDERWATER_ST"} & set(instrument.name for instrument in instruments_in_schedule) ) - or hasattr(ship_config, "ship_underwater_st_config") - or hasattr(ship_config, "adcp_config") + or ship_config.ship_underwater_st_config is not None + or ship_config.adcp_config is not None ): - print("Ship data will be downloaded") + print("Ship data will be downloaded. Please wait...") # Define all ship datasets to download, including bathymetry download_dict = { @@ -145,8 +147,8 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None complete_download(download_folder) click.echo("Ship data download based on space-time region completed.") - if "DRIFTER" in instruments_in_schedule: - print("Drifter data will be downloaded") + if InstrumentType.DRIFTER in instruments_in_schedule: + print("Drifter data will be downloaded. Please wait...") drifter_download_dict = { "UVdata": { "dataset_id": "cmems_mod_glo_phy-cur_anfc_0.083deg_PT6H-i", @@ -188,8 +190,8 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None complete_download(download_folder) click.echo("Drifter data download based on space-time region completed.") - if "ARGO_FLOAT" in instruments_in_schedule: - print("Argo float data will be downloaded") + if InstrumentType.ARGO_FLOAT in instruments_in_schedule: + print("Argo float data will be downloaded. Please wait...") argo_download_dict = { "UVdata": { "dataset_id": "cmems_mod_glo_phy-cur_anfc_0.083deg_PT6H-i", From 91a28d633fefa1947fe1b3d8ae3d946cd3d3a763 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 04/10] Managing conflicts on branch. 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 | 13 ------------- 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(+), 27 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 43ffe68d..00000000 --- a/src/virtualship/expedition/instrument_type.py +++ /dev/null @@ -1,13 +0,0 @@ -"""InstrumentType Enum.""" - -from enum import Enum - - -class InstrumentType(Enum): - """Types of instruments.""" - - CTD = "CTD" - CTD_BGC = "CTD_BGC" - 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 848d5d63..5aa85f26 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 1ae51d3f41bded49cff2eb4bc07f0cace0fbc21e 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 05/10] 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 5aa85f26..6dbbb49c 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") From 3aed6850e46492e9e9293f8da827753fb332b8c0 Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Wed, 30 Apr 2025 15:13:08 +0200 Subject: [PATCH 06/10] update init command to use CTD_BGC as new instrument when making schedule --- src/virtualship/expedition/ship_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/virtualship/expedition/ship_config.py b/src/virtualship/expedition/ship_config.py index 4f238b36..062b3784 100644 --- a/src/virtualship/expedition/ship_config.py +++ b/src/virtualship/expedition/ship_config.py @@ -20,6 +20,7 @@ class InstrumentType(Enum): """Types of instruments.""" CTD = "CTD" + CTD_BGC = "CTD_BGC" DRIFTER = "DRIFTER" ARGO_FLOAT = "ARGO_FLOAT" XBT = "XBT" From 938052c9aaeae148d2b0eb3d43d5193cf3cb9087 Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Fri, 9 May 2025 10:54:57 +0200 Subject: [PATCH 07/10] add configuration for CTD_BGC --- src/virtualship/expedition/ship_config.py | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/virtualship/expedition/ship_config.py b/src/virtualship/expedition/ship_config.py index 062b3784..c22b673e 100644 --- a/src/virtualship/expedition/ship_config.py +++ b/src/virtualship/expedition/ship_config.py @@ -81,6 +81,28 @@ def _validate_stationkeeping_time(cls, value: int | float | timedelta) -> timede return _validate_numeric_mins_to_timedelta(value) +class CTD_BGCConfig(pydantic.BaseModel): + """Configuration for CTD_BGC instrument.""" + + stationkeeping_time: timedelta = pydantic.Field( + serialization_alias="stationkeeping_time_minutes", + validation_alias="stationkeeping_time_minutes", + gt=timedelta(), + ) + min_depth_meter: float = pydantic.Field(le=0.0) + max_depth_meter: float = pydantic.Field(le=0.0) + + model_config = pydantic.ConfigDict(populate_by_name=True) + + @pydantic.field_serializer("stationkeeping_time") + def _serialize_stationkeeping_time(self, value: timedelta, _info): + return value.total_seconds() / 60.0 + + @pydantic.field_validator("stationkeeping_time", mode="before") + def _validate_stationkeeping_time(cls, value: int | float | timedelta) -> timedelta: + return _validate_numeric_mins_to_timedelta(value) + + class ShipUnderwaterSTConfig(pydantic.BaseModel): """Configuration for underwater ST.""" @@ -160,6 +182,13 @@ class ShipConfig(pydantic.BaseModel): If None, no CTDs can be cast. """ + ctd_bgc_config: CTD_BGCConfig | None = None + """ + CTD_BGC configuration. + + If None, no BGC CTDs can be cast. + """ + ship_underwater_st_config: ShipUnderwaterSTConfig | None = None """ Ship underwater salinity temperature measurementconfiguration. @@ -240,6 +269,7 @@ def verify(self, schedule: Schedule) -> None: "DRIFTER", "XBT", "CTD", + "CTD_BGC", ]: # TODO make instrument names consistent capitals or lowercase throughout codebase if hasattr(self, instrument.lower() + "_config") and not any( instrument == schedule_instrument.name @@ -249,6 +279,7 @@ def verify(self, schedule: Schedule) -> None: setattr(self, instrument.lower() + "_config", None) # verify instruments in schedule have configuration + # TODO: the ConfigError message could be improved to explain that the **schedule** file has X instrument but the **ship_config** file does not for instrument in instruments_in_schedule: try: InstrumentType(instrument) @@ -267,6 +298,12 @@ def verify(self, schedule: Schedule) -> None: raise ConfigError( "Planning has a waypoint with CTD instrument, but configuration does not configure CTDs." ) + if instrument == InstrumentType.CTD_BGC and ( + not hasattr(self, "ctd_bgc_config") or self.ctd_bgc_config is None + ): + raise ConfigError( + "Planning has a waypoint with CTD_BGC instrument, but configuration does not configure CTD_BGCs." + ) if instrument == InstrumentType.DRIFTER and ( not hasattr(self, "drifter_config") or self.drifter_config is None ): From 21ad1c68b1426343bfcb7ae824d94b887bdba9b2 Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Fri, 9 May 2025 11:09:45 +0200 Subject: [PATCH 08/10] add bgc data download option for CTD_BGC instrument --- src/virtualship/cli/_fetch.py | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 2e09dec2..386e6623 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -238,6 +238,50 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None complete_download(download_folder) click.echo("Argo_float data download based on space-time region completed.") + if InstrumentType.CTD_BGC in instruments_in_schedule: + print("CTD_BGC data will be downloaded. Please wait...") + + ctd_bgc_download_dict = { + "o2data": { + "dataset_id": "cmems_mod_glo_bgc-bio_anfc_0.25deg_P1D-m", + "variables": ["o2"], + "output_filename": "ctd_bgc_o2.nc", + }, + "chlorodata": { + "dataset_id": "cmems_mod_glo_bgc-pft_anfc_0.25deg_P1D-m", + "variables": ["chl"], + "output_filename": "ctd_bgc_chloro.nc", + }, + } + + # Iterate over all datasets and download each based on space_time_region + try: + for dataset in ctd_bgc_download_dict.values(): + copernicusmarine.subset( + dataset_id=dataset["dataset_id"], + variables=dataset["variables"], + minimum_longitude=spatial_range.minimum_longitude - 3.0, + maximum_longitude=spatial_range.maximum_longitude + 3.0, + minimum_latitude=spatial_range.minimum_latitude - 3.0, + maximum_latitude=spatial_range.maximum_latitude + 3.0, + start_datetime=start_datetime, + end_datetime=end_datetime + timedelta(days=21), + minimum_depth=abs(1), + maximum_depth=abs(spatial_range.maximum_depth), + output_filename=dataset["output_filename"], + output_directory=download_folder, + username=username, + password=password, + overwrite=True, + coordinates_selection_method="outside", + ) + except InvalidUsernameOrPassword as e: + shutil.rmtree(download_folder) + raise e + + complete_download(download_folder) + click.echo("CTD_BGC data download based on space-time region completed.") + def _hash(s: str, *, length: int) -> str: """Create a hash of a string.""" From 956e395412541abd0796fb31220279d64aae7a9a Mon Sep 17 00:00:00 2001 From: j-atkins <106238905+j-atkins@users.noreply.github.com> Date: Fri, 9 May 2025 16:47:44 +0200 Subject: [PATCH 09/10] add CTD_BGC to instruments which prompts ship data download --- src/virtualship/cli/_fetch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index 386e6623..b1cfde2a 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -87,7 +87,7 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None if ( ( - {"XBT", "CTD", "SHIP_UNDERWATER_ST"} + {"XBT", "CTD", "CDT_BGC", "SHIP_UNDERWATER_ST"} & set(instrument.name for instrument in instruments_in_schedule) ) or ship_config.ship_underwater_st_config is not None From b2b7858a3ddd738baf3fe98d52f963f114160efe Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Thu, 15 May 2025 10:33:04 +0200 Subject: [PATCH 10/10] Review feedback on complete_download --- src/virtualship/cli/_fetch.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/virtualship/cli/_fetch.py b/src/virtualship/cli/_fetch.py index b1cfde2a..f07c5b92 100644 --- a/src/virtualship/cli/_fetch.py +++ b/src/virtualship/cli/_fetch.py @@ -144,7 +144,6 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None shutil.rmtree(download_folder) raise e - complete_download(download_folder) click.echo("Ship data download based on space-time region completed.") if InstrumentType.DRIFTER in instruments_in_schedule: @@ -187,7 +186,6 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None shutil.rmtree(download_folder) raise e - complete_download(download_folder) click.echo("Drifter data download based on space-time region completed.") if InstrumentType.ARGO_FLOAT in instruments_in_schedule: @@ -235,7 +233,6 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None shutil.rmtree(download_folder) raise e - complete_download(download_folder) click.echo("Argo_float data download based on space-time region completed.") if InstrumentType.CTD_BGC in instruments_in_schedule: @@ -279,9 +276,10 @@ def _fetch(path: str | Path, username: str | None, password: str | None) -> None shutil.rmtree(download_folder) raise e - complete_download(download_folder) click.echo("CTD_BGC data download based on space-time region completed.") + complete_download(download_folder) + def _hash(s: str, *, length: int) -> str: """Create a hash of a string."""