Skip to content

Commit 995a6e5

Browse files
committed
fixing bugs associated with BGC data access
1 parent e9a0c54 commit 995a6e5

File tree

3 files changed

+38
-37
lines changed

3 files changed

+38
-37
lines changed

src/virtualship/cli/_run.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import os
55
import shutil
6+
import time
67
from pathlib import Path
78

89
import pyproj
@@ -39,12 +40,9 @@ def _run(expedition_dir: str | Path) -> None:
3940
4041
:param expedition_dir: The base directory for the expedition.
4142
"""
42-
# ################################# TEMPORARY TIMER: START #################################
43-
import time
44-
43+
# start timing
4544
start_time = time.time()
4645
print("[TIMER] Expedition started...")
47-
# ################################# TEMPORARY TIMER: START #################################
4846

4947
print("\n╔═════════════════════════════════════════════════╗")
5048
print("║ VIRTUALSHIP EXPEDITION STATUS ║")
@@ -139,11 +137,10 @@ def _run(expedition_dir: str | Path) -> None:
139137
)
140138
print("\n------------- END -------------\n")
141139

142-
################################# TEMPORARY TIMER: END #################################
140+
# end timing
143141
end_time = time.time()
144142
elapsed = end_time - start_time
145-
print(f"[TIMER] Expedition completed in {elapsed:.2f} seconds.")
146-
################################# TEMPORARY TIMER: END #################################
143+
print(f"[TIMER] Expedition completed in {elapsed / 60.0:.2f} minutes.")
147144

148145

149146
def _load_checkpoint(expedition_dir: Path) -> Checkpoint | None:

src/virtualship/instruments/argo_float.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def __init__(self, expedition, directory):
147147
}
148148
variables = {"U": "uo", "V": "vo", "S": "so", "T": "thetao"}
149149
buffer_spec = {
150-
"latlon": 6.0, # [degrees]
150+
"latlon": 3.0, # [degrees]
151151
"time": 21.0, # [days]
152152
}
153153

src/virtualship/instruments/base.py

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import abc
2+
from collections import OrderedDict
23
from datetime import timedelta
34
from pathlib import Path
45
from typing import TYPE_CHECKING
@@ -8,6 +9,7 @@
89
from yaspin import yaspin
910

1011
from parcels import FieldSet
12+
from virtualship.errors import CopernicusCatalogueError
1113
from virtualship.utils import (
1214
COPERNICUSMARINE_PHYS_VARIABLES,
1315
_get_bathy_data,
@@ -43,7 +45,8 @@ def __init__(
4345
self.expedition = expedition
4446
self.directory = directory
4547
self.filenames = filenames
46-
self.variables = variables
48+
49+
self.variables = OrderedDict(variables)
4750
self.dimensions = {
4851
"lon": "longitude",
4952
"lat": "latitude",
@@ -61,8 +64,8 @@ def load_input_data(self) -> FieldSet:
6164
try:
6265
fieldset = self._generate_fieldset()
6366
except Exception as e:
64-
raise FileNotFoundError(
65-
f"Failed to load input data directly from Copernicus Marine for instrument '{self.name}'.Original error: {e}"
67+
raise CopernicusCatalogueError(
68+
f"Failed to load input data directly from Copernicus Marine for instrument '{self.name}'. Original error: {e}"
6669
) from e
6770

6871
# interpolation methods
@@ -92,22 +95,18 @@ def simulate(self, data_dir: Path, measurements: list, out_path: str | Path):
9295

9396
def execute(self, measurements: list, out_path: str | Path) -> None:
9497
"""Run instrument simulation."""
95-
TMP = False
96-
if not TMP:
97-
if not self.verbose_progress:
98-
with yaspin(
99-
text=f"Simulating {self.name} measurements... ",
100-
side="right",
101-
spinner=ship_spinner,
102-
) as spinner:
103-
self.simulate(measurements, out_path)
104-
spinner.ok("✅\n")
105-
else:
106-
print(f"Simulating {self.name} measurements... ")
98+
if not self.verbose_progress:
99+
with yaspin(
100+
text=f"Simulating {self.name} measurements... ",
101+
side="right",
102+
spinner=ship_spinner,
103+
) as spinner:
107104
self.simulate(measurements, out_path)
108-
print("\n")
105+
spinner.ok("✅\n")
109106
else:
107+
print(f"Simulating {self.name} measurements... ")
110108
self.simulate(measurements, out_path)
109+
print("\n")
111110

112111
def _get_copernicus_ds(
113112
self,
@@ -122,11 +121,10 @@ def _get_copernicus_ds(
122121
variable=var if not physical else None,
123122
)
124123

125-
latlon_buffer = self.buffer_spec.get("latlon") if self.buffer_spec else 0.0
126-
time_buffer = self.buffer_spec.get("time") if self.buffer_spec else 0.0
127-
128-
depth_min = self.limit_spec.get("depth_min") if self.limit_spec else None
129-
depth_max = self.limit_spec.get("depth_max") if self.limit_spec else None
124+
latlon_buffer = self._get_spec_value("buffer", "latlon", 0.0)
125+
time_buffer = self._get_spec_value("buffer", "time", 0.0)
126+
depth_min = self._get_spec_value("limit", "depth_min", None)
127+
depth_max = self._get_spec_value("limit", "depth_max", None)
130128

131129
return copernicusmarine.open_dataset(
132130
dataset_id=product_id,
@@ -151,21 +149,27 @@ def _generate_fieldset(self) -> FieldSet:
151149
"""
152150
Fieldset per variable then combine.
153151
154-
Avoids issues when creating one FieldSet of ds's sourced from different Copernicus Marine product IDs, which is often the case for BGC variables.
155-
152+
Avoids issues when creating directly one FieldSet of ds's sourced from different Copernicus Marine product IDs, which is often the case for BGC variables.
156153
"""
157154
fieldsets_list = []
158-
for key, var in self.variables.items():
155+
keys = list(self.variables.keys())
156+
for key in keys:
157+
var = self.variables[key]
159158
physical = True if var in COPERNICUSMARINE_PHYS_VARIABLES else False
160159
ds = self._get_copernicus_ds(physical=physical, var=var)
161-
fieldset = FieldSet.from_xarray_dataset(
160+
fs = FieldSet.from_xarray_dataset(
162161
ds, {key: var}, self.dimensions, mesh="spherical"
163162
)
164-
fieldsets_list.append(fieldset)
163+
fieldsets_list.append(fs)
164+
165165
base_fieldset = fieldsets_list[0]
166166
if len(fieldsets_list) > 1:
167-
for fs, key in zip(
168-
fieldsets_list[1:], list(self.variables.keys())[1:], strict=True
169-
):
167+
for fs, key in zip(fieldsets_list[1:], keys[1:], strict=True):
170168
base_fieldset.add_field(getattr(fs, key))
169+
171170
return base_fieldset
171+
172+
def _get_spec_value(self, spec_type: str, key: str, default=None):
173+
"""Helper to extract a value from buffer_spec or limit_spec."""
174+
spec = self.buffer_spec if spec_type == "buffer" else self.limit_spec
175+
return spec.get(key) if spec and spec.get(key) is not None else default

0 commit comments

Comments
 (0)