roms-tools 2.2.1__py3-none-any.whl → 2.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ci/environment.yml +1 -0
- roms_tools/__init__.py +2 -0
- roms_tools/analysis/roms_output.py +590 -0
- roms_tools/{setup/download.py → download.py} +3 -0
- roms_tools/{setup/plot.py → plot.py} +34 -28
- roms_tools/setup/boundary_forcing.py +199 -203
- roms_tools/setup/datasets.py +60 -136
- roms_tools/setup/grid.py +40 -67
- roms_tools/setup/initial_conditions.py +249 -247
- roms_tools/setup/nesting.py +6 -27
- roms_tools/setup/river_forcing.py +41 -76
- roms_tools/setup/surface_forcing.py +125 -75
- roms_tools/setup/tides.py +31 -51
- roms_tools/setup/topography.py +1 -1
- roms_tools/setup/utils.py +44 -224
- roms_tools/tests/test_analysis/test_roms_output.py +269 -0
- roms_tools/tests/{test_setup/test_regrid.py → test_regrid.py} +1 -1
- roms_tools/tests/test_setup/test_boundary_forcing.py +221 -58
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +5 -3
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +156 -121
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +2 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +4 -4
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +4 -4
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/f/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/pm/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/pn/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +2 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +6 -4
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_w/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/abs_time/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ocean_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zmetadata +30 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zmetadata +30 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/0.0 +0 -0
- roms_tools/tests/test_setup/test_datasets.py +1 -1
- roms_tools/tests/test_setup/test_grid.py +1 -14
- roms_tools/tests/test_setup/test_initial_conditions.py +205 -67
- roms_tools/tests/test_setup/test_nesting.py +0 -16
- roms_tools/tests/test_setup/test_river_forcing.py +9 -37
- roms_tools/tests/test_setup/test_surface_forcing.py +103 -74
- roms_tools/tests/test_setup/test_tides.py +5 -17
- roms_tools/tests/test_setup/test_topography.py +1 -1
- roms_tools/tests/test_setup/test_utils.py +57 -1
- roms_tools/tests/{test_utils.py → test_tiling/test_partition.py} +1 -1
- roms_tools/tiling/partition.py +338 -0
- roms_tools/utils.py +310 -276
- roms_tools/vertical_coordinate.py +227 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/METADATA +1 -1
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/RECORD +151 -142
- roms_tools/setup/vertical_coordinate.py +0 -109
- /roms_tools/{setup/regrid.py → regrid.py} +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/LICENSE +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/WHEEL +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/top_level.txt +0 -0
roms_tools/setup/nesting.py
CHANGED
|
@@ -4,19 +4,19 @@ from scipy.interpolate import griddata
|
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
5
|
from typing import Dict, Union
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
|
|
7
|
+
import logging
|
|
8
|
+
from scipy.interpolate import interp1d
|
|
9
|
+
from roms_tools import Grid
|
|
10
|
+
from roms_tools.plot import _plot_nesting
|
|
11
|
+
from roms_tools.utils import save_datasets
|
|
8
12
|
from roms_tools.setup.utils import (
|
|
9
13
|
interpolate_from_rho_to_u,
|
|
10
14
|
interpolate_from_rho_to_v,
|
|
11
15
|
get_boundary_coords,
|
|
12
16
|
wrap_longitudes,
|
|
13
|
-
save_datasets,
|
|
14
17
|
_to_yaml,
|
|
15
18
|
_from_yaml,
|
|
16
19
|
)
|
|
17
|
-
from roms_tools.setup.plot import _plot_nesting
|
|
18
|
-
import logging
|
|
19
|
-
from scipy.interpolate import interp1d
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@dataclass(frozen=True, kw_only=True)
|
|
@@ -114,37 +114,18 @@ class Nesting:
|
|
|
114
114
|
self,
|
|
115
115
|
filepath: Union[str, Path],
|
|
116
116
|
filepath_child_grid: Union[str, Path],
|
|
117
|
-
np_eta: int = None,
|
|
118
|
-
np_xi: int = None,
|
|
119
117
|
) -> None:
|
|
120
118
|
"""Save the nesting and child grid file to netCDF4 files. The child grid file is
|
|
121
119
|
required because the topography and mask of the child grid has been modified.
|
|
122
120
|
|
|
123
|
-
This method allows saving the nesting and child grid data either each as a single file or each partitioned into multiple files, based on the provided options. The dataset can be saved in two modes:
|
|
124
|
-
|
|
125
|
-
1. **Single File Mode (default)**:
|
|
126
|
-
- If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file.
|
|
127
|
-
- The file is named based on the provided `filepath`, with `.nc` automatically appended to the filename.
|
|
128
|
-
|
|
129
|
-
2. **Partitioned Mode**:
|
|
130
|
-
- If either `np_eta` or `np_xi` is specified, the dataset is partitioned spatially along the `eta` and `xi` axes into tiles.
|
|
131
|
-
- Each tile is saved as a separate netCDF4 file. Filenames will be modified with an index to represent each partition, e.g., `"filepath_YYYYMM.0.nc"`, `"filepath_YYYYMM.1.nc"`, etc.
|
|
132
|
-
|
|
133
121
|
Parameters
|
|
134
122
|
----------
|
|
135
123
|
filepath : Union[str, Path]
|
|
136
124
|
The base path and filename for the output files. The filenames will include the specified path and the `.nc` extension.
|
|
137
|
-
If partitioning is used, additional indices will be appended to the filenames, e.g., `"filepath.0.nc"`, `"filepath.1.nc"`, etc.
|
|
138
125
|
|
|
139
126
|
filepath_child_grid : Union[str, Path]
|
|
140
127
|
The base path and filename for saving the childe grid file.
|
|
141
128
|
|
|
142
|
-
np_eta : int, optional
|
|
143
|
-
The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed along the `eta` axis.
|
|
144
|
-
|
|
145
|
-
np_xi : int, optional
|
|
146
|
-
The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed along the `xi` axis.
|
|
147
|
-
|
|
148
129
|
Returns
|
|
149
130
|
-------
|
|
150
131
|
List[Path]
|
|
@@ -164,9 +145,7 @@ class Nesting:
|
|
|
164
145
|
dataset_list = [self.ds, self.child_grid.ds]
|
|
165
146
|
output_filenames = [str(filepath), str(filepath_child_grid)]
|
|
166
147
|
|
|
167
|
-
saved_filenames = save_datasets(
|
|
168
|
-
dataset_list, output_filenames, np_eta=np_eta, np_xi=np_xi
|
|
169
|
-
)
|
|
148
|
+
saved_filenames = save_datasets(dataset_list, output_filenames)
|
|
170
149
|
|
|
171
150
|
return saved_filenames
|
|
172
151
|
|
|
@@ -2,24 +2,24 @@ import xarray as xr
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import logging
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
|
|
5
|
+
import cartopy.crs as ccrs
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from typing import Dict, Union, List
|
|
8
|
-
from roms_tools.setup.datasets import DaiRiverDataset
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
import matplotlib.pyplot as plt
|
|
10
|
+
from roms_tools import Grid
|
|
11
|
+
from roms_tools.plot import _get_projection, _add_field_to_ax
|
|
12
|
+
from roms_tools.utils import save_datasets
|
|
13
|
+
from roms_tools.setup.datasets import DaiRiverDataset
|
|
11
14
|
from roms_tools.setup.utils import (
|
|
12
15
|
get_target_coords,
|
|
13
16
|
gc_dist,
|
|
14
17
|
substitute_nans_by_fillvalue,
|
|
15
18
|
convert_to_roms_time,
|
|
16
|
-
save_datasets,
|
|
17
19
|
_to_yaml,
|
|
18
20
|
_from_yaml,
|
|
19
21
|
get_variable_metadata,
|
|
20
22
|
)
|
|
21
|
-
from roms_tools.setup.plot import _get_projection, _add_field_to_ax
|
|
22
|
-
import cartopy.crs as ccrs
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
@dataclass(frozen=True, kw_only=True)
|
|
@@ -91,8 +91,9 @@ class RiverForcing:
|
|
|
91
91
|
object.__setattr__(self, "original_indices", original_indices)
|
|
92
92
|
|
|
93
93
|
if len(original_indices["station"]) > 0:
|
|
94
|
-
self._move_rivers_to_closest_coast(target_coords, data)
|
|
95
94
|
ds = self._create_river_forcing(data)
|
|
95
|
+
self._move_rivers_to_closest_coast(target_coords, data)
|
|
96
|
+
ds = self._write_indices_into_dataset(ds)
|
|
96
97
|
self._validate(ds)
|
|
97
98
|
|
|
98
99
|
for var_name in ds.data_vars:
|
|
@@ -345,49 +346,44 @@ class RiverForcing:
|
|
|
345
346
|
"xi_rho": indices[2],
|
|
346
347
|
"name": names,
|
|
347
348
|
}
|
|
348
|
-
self._write_indices_into_grid_file(indices)
|
|
349
349
|
object.__setattr__(self, "updated_indices", indices)
|
|
350
350
|
|
|
351
|
-
def
|
|
352
|
-
"""
|
|
353
|
-
variable.
|
|
351
|
+
def _write_indices_into_dataset(self, ds):
|
|
352
|
+
"""Adds river location indices to the dataset as the "river_location" variable.
|
|
354
353
|
|
|
355
|
-
This method checks if the
|
|
356
|
-
If it does, the method removes it. Then, it creates a new
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
cell indices (eta_rho and xi_rho).
|
|
354
|
+
This method checks if the "river_location" variable already exists in the dataset.
|
|
355
|
+
If it does, the method removes it. Then, it creates a new "river_location" variable
|
|
356
|
+
using river station indices from `self.updated_indices` and assigns it to the dataset.
|
|
357
|
+
The indices specify the river station locations in terms of eta_rho and xi_rho grid cell indices.
|
|
360
358
|
|
|
361
|
-
Parameters
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
It must contain the following keys:
|
|
366
|
-
- "name" (list or array): Names of the river stations.
|
|
367
|
-
- "station" (list or array): River station identifiers.
|
|
368
|
-
- "eta_rho" (list or array): The eta (row) index for each river location.
|
|
369
|
-
- "xi_rho" (list or array): The xi (column) index for each river location.
|
|
359
|
+
Parameters
|
|
360
|
+
----------
|
|
361
|
+
ds : xarray.Dataset
|
|
362
|
+
The dataset to which the "river_location" variable will be added.
|
|
370
363
|
|
|
371
|
-
Returns
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
364
|
+
Returns
|
|
365
|
+
-------
|
|
366
|
+
xarray.Dataset
|
|
367
|
+
The modified dataset with the "river_location" variable added.
|
|
375
368
|
"""
|
|
376
369
|
|
|
377
|
-
if "
|
|
378
|
-
ds =
|
|
379
|
-
object.__setattr__(self.grid, "ds", ds)
|
|
370
|
+
if "river_location" in ds:
|
|
371
|
+
ds = ds.drop_vars("river_location")
|
|
380
372
|
|
|
381
373
|
river_locations = xr.zeros_like(self.grid.ds.mask_rho)
|
|
382
|
-
for i in range(len(
|
|
383
|
-
station =
|
|
384
|
-
eta_index =
|
|
385
|
-
xi_index =
|
|
374
|
+
for i in range(len(self.updated_indices["name"])):
|
|
375
|
+
station = self.updated_indices["station"][i]
|
|
376
|
+
eta_index = self.updated_indices["eta_rho"][i]
|
|
377
|
+
xi_index = self.updated_indices["xi_rho"][i]
|
|
386
378
|
river_locations[eta_index, xi_index] = station + 2
|
|
387
379
|
|
|
388
|
-
river_locations.attrs["long_name"] = "River volume
|
|
380
|
+
river_locations.attrs["long_name"] = "River index plus local volume fraction"
|
|
389
381
|
river_locations.attrs["units"] = "none"
|
|
390
|
-
|
|
382
|
+
ds["river_location"] = river_locations
|
|
383
|
+
|
|
384
|
+
ds = ds.drop_vars(["lat_rho", "lon_rho"])
|
|
385
|
+
|
|
386
|
+
return ds
|
|
391
387
|
|
|
392
388
|
def _validate(self, ds):
|
|
393
389
|
"""Validates the dataset by checking for NaN values in river forcing data.
|
|
@@ -416,16 +412,13 @@ class RiverForcing:
|
|
|
416
412
|
"""Plots the original and updated river locations on a map projection."""
|
|
417
413
|
|
|
418
414
|
field = self.grid.ds.mask_rho
|
|
419
|
-
field = field.assign_coords(
|
|
420
|
-
{"lon": self.grid.ds.lon_rho, "lat": self.grid.ds.lat_rho}
|
|
421
|
-
)
|
|
422
415
|
vmax = 3
|
|
423
416
|
vmin = 0
|
|
424
417
|
cmap = plt.colormaps.get_cmap("Blues")
|
|
425
418
|
kwargs = {"vmax": vmax, "vmin": vmin, "cmap": cmap}
|
|
426
419
|
|
|
427
|
-
lon_deg =
|
|
428
|
-
lat_deg =
|
|
420
|
+
lon_deg = self.grid.ds.lon_rho
|
|
421
|
+
lat_deg = self.grid.ds.lat_rho
|
|
429
422
|
|
|
430
423
|
# check if North or South pole are in domain
|
|
431
424
|
if lat_deg.max().values > 89 or lat_deg.min().values < -89:
|
|
@@ -435,6 +428,7 @@ class RiverForcing:
|
|
|
435
428
|
|
|
436
429
|
if self.grid.straddle:
|
|
437
430
|
lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
|
|
431
|
+
field = field.assign_coords({"lon": lon_deg, "lat": lat_deg})
|
|
438
432
|
|
|
439
433
|
trans = _get_projection(lon_deg, lat_deg)
|
|
440
434
|
|
|
@@ -594,37 +588,13 @@ class RiverForcing:
|
|
|
594
588
|
def save(
|
|
595
589
|
self,
|
|
596
590
|
filepath: Union[str, Path],
|
|
597
|
-
filepath_grid: Union[str, Path],
|
|
598
|
-
np_eta: int = None,
|
|
599
|
-
np_xi: int = None,
|
|
600
591
|
) -> None:
|
|
601
|
-
"""Save the river forcing
|
|
602
|
-
required because a new field `river_flux` has been added.
|
|
603
|
-
|
|
604
|
-
This method allows saving the river forcing and grid data either each as a single file or each partitioned into multiple files, based on the provided options. The dataset can be saved in two modes:
|
|
605
|
-
|
|
606
|
-
1. **Single File Mode (default)**:
|
|
607
|
-
- If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file.
|
|
608
|
-
- The file is named based on the provided `filepath`, with `.nc` automatically appended to the filename.
|
|
609
|
-
|
|
610
|
-
2. **Partitioned Mode**:
|
|
611
|
-
- If either `np_eta` or `np_xi` is specified, the dataset is partitioned spatially along the `eta` and `xi` axes into tiles.
|
|
612
|
-
- Each tile is saved as a separate netCDF4 file. Filenames will be modified with an index to represent each partition, e.g., `"filepath_YYYYMM.0.nc"`, `"filepath_YYYYMM.1.nc"`, etc.
|
|
592
|
+
"""Save the river forcing to netCDF4 file.
|
|
613
593
|
|
|
614
594
|
Parameters
|
|
615
595
|
----------
|
|
616
596
|
filepath : Union[str, Path]
|
|
617
|
-
The base path and filename for the output files.
|
|
618
|
-
If partitioning is used, additional indices will be appended to the filenames, e.g., `"filepath.0.nc"`, `"filepath.1.nc"`, etc.
|
|
619
|
-
|
|
620
|
-
filepath_grid : Union[str, Path]
|
|
621
|
-
The base path and filename for saving the grid file.
|
|
622
|
-
|
|
623
|
-
np_eta : int, optional
|
|
624
|
-
The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed along the `eta` axis.
|
|
625
|
-
|
|
626
|
-
np_xi : int, optional
|
|
627
|
-
The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed along the `xi` axis.
|
|
597
|
+
The base path and filename for the output files.
|
|
628
598
|
|
|
629
599
|
Returns
|
|
630
600
|
-------
|
|
@@ -634,20 +604,15 @@ class RiverForcing:
|
|
|
634
604
|
|
|
635
605
|
# Ensure filepath is a Path object
|
|
636
606
|
filepath = Path(filepath)
|
|
637
|
-
filepath_grid = Path(filepath_grid)
|
|
638
607
|
|
|
639
608
|
# Remove ".nc" suffix if present
|
|
640
609
|
if filepath.suffix == ".nc":
|
|
641
610
|
filepath = filepath.with_suffix("")
|
|
642
|
-
if filepath_grid.suffix == ".nc":
|
|
643
|
-
filepath_grid = filepath_grid.with_suffix("")
|
|
644
611
|
|
|
645
|
-
dataset_list = [self.ds
|
|
646
|
-
output_filenames = [str(filepath)
|
|
612
|
+
dataset_list = [self.ds]
|
|
613
|
+
output_filenames = [str(filepath)]
|
|
647
614
|
|
|
648
|
-
saved_filenames = save_datasets(
|
|
649
|
-
dataset_list, output_filenames, np_eta=np_eta, np_xi=np_xi
|
|
650
|
-
)
|
|
615
|
+
saved_filenames = save_datasets(dataset_list, output_filenames)
|
|
651
616
|
|
|
652
617
|
return saved_filenames
|
|
653
618
|
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import xarray as xr
|
|
2
2
|
import importlib.metadata
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from roms_tools.setup.grid import Grid
|
|
5
4
|
from datetime import datetime
|
|
6
5
|
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import logging
|
|
7
9
|
from typing import Dict, Union, List
|
|
8
|
-
from roms_tools
|
|
10
|
+
from roms_tools import Grid
|
|
11
|
+
from roms_tools.utils import save_datasets
|
|
12
|
+
from roms_tools.regrid import LateralRegrid
|
|
13
|
+
from roms_tools.plot import _plot
|
|
9
14
|
from roms_tools.setup.datasets import (
|
|
10
15
|
ERA5Dataset,
|
|
11
16
|
ERA5Correction,
|
|
@@ -18,15 +23,11 @@ from roms_tools.setup.utils import (
|
|
|
18
23
|
interpolate_from_climatology,
|
|
19
24
|
get_variable_metadata,
|
|
20
25
|
group_dataset,
|
|
21
|
-
save_datasets,
|
|
22
26
|
rotate_velocities,
|
|
23
27
|
convert_to_roms_time,
|
|
24
28
|
_to_yaml,
|
|
25
29
|
_from_yaml,
|
|
26
30
|
)
|
|
27
|
-
from roms_tools.setup.plot import _plot
|
|
28
|
-
import matplotlib.pyplot as plt
|
|
29
|
-
from pathlib import Path
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
@dataclass(frozen=True, kw_only=True)
|
|
@@ -59,9 +60,14 @@ class SurfaceForcing:
|
|
|
59
60
|
- "bgc": for biogeochemical forcing.
|
|
60
61
|
|
|
61
62
|
correct_radiation : bool
|
|
62
|
-
Whether to correct shortwave radiation. Default is
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
Whether to correct shortwave radiation. Default is True.
|
|
64
|
+
coarse_grid_mode : str, optional
|
|
65
|
+
Specifies whether to interpolate onto grid coarsened by a factor of two. Options are:
|
|
66
|
+
|
|
67
|
+
- "auto" (default): Automatically decide based on the comparison of source and target spatial resolutions.
|
|
68
|
+
- "always": Always interpolate onto the coarse grid.
|
|
69
|
+
- "never": Never use the coarse grid; interpolate onto the fine grid instead.
|
|
70
|
+
|
|
65
71
|
model_reference_date : datetime, optional
|
|
66
72
|
Reference date for the model. Default is January 1, 2000.
|
|
67
73
|
use_dask: bool, optional
|
|
@@ -88,8 +94,8 @@ class SurfaceForcing:
|
|
|
88
94
|
end_time: datetime
|
|
89
95
|
source: Dict[str, Union[str, Path, List[Union[str, Path]]]]
|
|
90
96
|
type: str = "physics"
|
|
91
|
-
correct_radiation: bool =
|
|
92
|
-
|
|
97
|
+
correct_radiation: bool = True
|
|
98
|
+
coarse_grid_mode: str = "auto"
|
|
93
99
|
model_reference_date: datetime = datetime(2000, 1, 1)
|
|
94
100
|
use_dask: bool = False
|
|
95
101
|
bypass_validation: bool = False
|
|
@@ -99,10 +105,23 @@ class SurfaceForcing:
|
|
|
99
105
|
def __post_init__(self):
|
|
100
106
|
|
|
101
107
|
self._input_checks()
|
|
108
|
+
data = self._get_data()
|
|
109
|
+
|
|
110
|
+
if self.coarse_grid_mode == "always":
|
|
111
|
+
use_coarse_grid = True
|
|
112
|
+
elif self.coarse_grid_mode == "never":
|
|
113
|
+
use_coarse_grid = False
|
|
114
|
+
elif self.coarse_grid_mode == "auto":
|
|
115
|
+
use_coarse_grid = self._determine_coarse_grid_usage(data)
|
|
116
|
+
if use_coarse_grid:
|
|
117
|
+
logging.info("Data will be interpolated onto grid coarsened by factor 2.")
|
|
118
|
+
else:
|
|
119
|
+
logging.info("Data will be interpolated onto fine grid.")
|
|
120
|
+
object.__setattr__(self, "use_coarse_grid", use_coarse_grid)
|
|
121
|
+
|
|
102
122
|
target_coords = get_target_coords(self.grid, self.use_coarse_grid)
|
|
103
123
|
object.__setattr__(self, "target_coords", target_coords)
|
|
104
124
|
|
|
105
|
-
data = self._get_data()
|
|
106
125
|
data.choose_subdomain(
|
|
107
126
|
target_coords,
|
|
108
127
|
buffer_points=20, # lateral fill needs some buffer from data margin
|
|
@@ -166,6 +185,47 @@ class SurfaceForcing:
|
|
|
166
185
|
{**self.source, "climatology": self.source.get("climatology", False)},
|
|
167
186
|
)
|
|
168
187
|
|
|
188
|
+
# Validate 'coarse_grid_mode'
|
|
189
|
+
valid_modes = ["auto", "always", "never"]
|
|
190
|
+
if self.coarse_grid_mode not in valid_modes:
|
|
191
|
+
raise ValueError(
|
|
192
|
+
f"`coarse_grid_mode` must be one of {valid_modes}, but got '{self.coarse_grid_mode}'."
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def _determine_coarse_grid_usage(self, data):
|
|
196
|
+
"""Determine if coarse grid interpolation should be used based on the resolution
|
|
197
|
+
of the dataset and the target grid.
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
data : object
|
|
202
|
+
The dataset object containing the data to be analyzed for grid spacing.
|
|
203
|
+
|
|
204
|
+
Returns
|
|
205
|
+
-------
|
|
206
|
+
use_coarse_grid : bool
|
|
207
|
+
Whether to use the coarse grid or not.
|
|
208
|
+
"""
|
|
209
|
+
# Get the target coordinates and select the subdomain of the data
|
|
210
|
+
target_coords = get_target_coords(self.grid, use_coarse_grid=False)
|
|
211
|
+
data_coords = data.choose_subdomain(
|
|
212
|
+
target_coords, buffer_points=1, return_coords_only=True
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Compute minimal grid spacing in the data subdomain
|
|
216
|
+
min_grid_spacing_data = data.compute_minimal_grid_spacing(data_coords)
|
|
217
|
+
|
|
218
|
+
# Compute the maximum grid spacing in the ROMS grid
|
|
219
|
+
max_grid_spacing = max((1 / self.grid.ds.pm).max(), (1 / self.grid.ds.pn).max())
|
|
220
|
+
|
|
221
|
+
# Determine whether to use coarse grid based on grid spacing comparison
|
|
222
|
+
if 2 * max_grid_spacing < min_grid_spacing_data:
|
|
223
|
+
use_coarse_grid = True
|
|
224
|
+
else:
|
|
225
|
+
use_coarse_grid = False
|
|
226
|
+
|
|
227
|
+
return use_coarse_grid
|
|
228
|
+
|
|
169
229
|
def _get_data(self):
|
|
170
230
|
|
|
171
231
|
data_dict = {
|
|
@@ -238,14 +298,14 @@ class SurfaceForcing:
|
|
|
238
298
|
"qair": {**default_info, "validate": True},
|
|
239
299
|
"rain": {**default_info, "validate": False},
|
|
240
300
|
"uwnd": {
|
|
241
|
-
"location": "
|
|
301
|
+
"location": "rho",
|
|
242
302
|
"is_vector": True,
|
|
243
303
|
"vector_pair": "vwnd",
|
|
244
304
|
"is_3d": False,
|
|
245
305
|
"validate": True,
|
|
246
306
|
},
|
|
247
307
|
"vwnd": {
|
|
248
|
-
"location": "
|
|
308
|
+
"location": "rho",
|
|
249
309
|
"is_vector": True,
|
|
250
310
|
"vector_pair": "uwnd",
|
|
251
311
|
"is_3d": False,
|
|
@@ -266,7 +326,7 @@ class SurfaceForcing:
|
|
|
266
326
|
def _apply_correction(self, processed_fields, data):
|
|
267
327
|
|
|
268
328
|
correction_data = self._get_correction_data()
|
|
269
|
-
#
|
|
329
|
+
# Match subdomain to forcing data to reuse the mask
|
|
270
330
|
coords_correction = {
|
|
271
331
|
"lat": data.ds[data.dim_names["latitude"]],
|
|
272
332
|
"lon": data.ds[data.dim_names["longitude"]],
|
|
@@ -275,23 +335,39 @@ class SurfaceForcing:
|
|
|
275
335
|
coords_correction, straddle=self.target_coords["straddle"]
|
|
276
336
|
)
|
|
277
337
|
correction_data.ds["mask"] = data.ds["mask"] # use mask from ERA5 data
|
|
338
|
+
correction_data.ds["time"] = correction_data.ds["time"].dt.days
|
|
339
|
+
|
|
278
340
|
correction_data.apply_lateral_fill()
|
|
279
|
-
# regrid
|
|
280
|
-
lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
|
|
281
|
-
corr_factor = lateral_regrid.apply(
|
|
282
|
-
correction_data.ds[correction_data.var_names["swr_corr"]]
|
|
283
|
-
)
|
|
284
341
|
|
|
285
|
-
#
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
time
|
|
290
|
-
|
|
342
|
+
# Temporal interpolation: Perform before spatial regridding for better performance
|
|
343
|
+
if self.use_dask:
|
|
344
|
+
# Perform temporal interpolation for each time slice to enforce chunking in time.
|
|
345
|
+
# This reduces memory usage by processing one time step at a time.
|
|
346
|
+
# The interpolated slices are then concatenated along the "time" dimension.
|
|
347
|
+
corr_factor = xr.concat(
|
|
348
|
+
[
|
|
349
|
+
interpolate_from_climatology(
|
|
350
|
+
correction_data.ds[correction_data.var_names["swr_corr"]],
|
|
351
|
+
correction_data.dim_names["time"],
|
|
352
|
+
time=time,
|
|
353
|
+
)
|
|
354
|
+
for time in processed_fields["swrad"].time
|
|
355
|
+
],
|
|
356
|
+
dim="time",
|
|
357
|
+
)
|
|
358
|
+
else:
|
|
359
|
+
# Interpolate across all time steps at once
|
|
360
|
+
corr_factor = interpolate_from_climatology(
|
|
361
|
+
correction_data.ds[correction_data.var_names["swr_corr"]],
|
|
362
|
+
correction_data.dim_names["time"],
|
|
363
|
+
time=processed_fields["swrad"].time,
|
|
364
|
+
)
|
|
291
365
|
|
|
292
|
-
|
|
366
|
+
# Spatial regridding
|
|
367
|
+
lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
|
|
368
|
+
corr_factor = lateral_regrid.apply(corr_factor)
|
|
293
369
|
|
|
294
|
-
|
|
370
|
+
processed_fields["swrad"] = processed_fields["swrad"] * corr_factor
|
|
295
371
|
|
|
296
372
|
return processed_fields
|
|
297
373
|
|
|
@@ -357,12 +433,8 @@ class SurfaceForcing:
|
|
|
357
433
|
|
|
358
434
|
for var_name in ds.data_vars:
|
|
359
435
|
if self.variable_info[var_name]["validate"]:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
elif self.variable_info[var_name]["location"] == "u":
|
|
363
|
-
mask = self.target_coords["mask_u"]
|
|
364
|
-
elif self.variable_info[var_name]["location"] == "v":
|
|
365
|
-
mask = self.target_coords["mask_v"]
|
|
436
|
+
# all variables are at rho-points
|
|
437
|
+
mask = self.target_coords["mask"]
|
|
366
438
|
nan_check(ds[var_name].isel(time=0), mask)
|
|
367
439
|
|
|
368
440
|
def _add_global_metadata(self, ds=None):
|
|
@@ -434,21 +506,23 @@ class SurfaceForcing:
|
|
|
434
506
|
raise ValueError(f"Variable '{var_name}' is not found in dataset.")
|
|
435
507
|
|
|
436
508
|
field = self.ds[var_name].isel(time=time)
|
|
509
|
+
|
|
437
510
|
if self.use_dask:
|
|
438
511
|
from dask.diagnostics import ProgressBar
|
|
439
512
|
|
|
440
513
|
with ProgressBar():
|
|
441
514
|
field = field.load()
|
|
442
515
|
|
|
443
|
-
title = field.long_name
|
|
444
|
-
|
|
445
516
|
field = field.where(self.target_coords["mask"])
|
|
446
517
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
518
|
+
lon_deg = self.target_coords["lon"]
|
|
519
|
+
lat_deg = self.target_coords["lat"]
|
|
520
|
+
if self.grid.straddle:
|
|
521
|
+
lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
|
|
522
|
+
field = field.assign_coords({"lon": lon_deg, "lat": lat_deg})
|
|
523
|
+
|
|
524
|
+
title = field.long_name
|
|
450
525
|
|
|
451
|
-
# choose colorbar
|
|
452
526
|
if var_name in ["uwnd", "vwnd"]:
|
|
453
527
|
vmax = max(field.max().values, -field.min().values)
|
|
454
528
|
vmin = -vmax
|
|
@@ -465,53 +539,35 @@ class SurfaceForcing:
|
|
|
465
539
|
kwargs = {"vmax": vmax, "vmin": vmin, "cmap": cmap}
|
|
466
540
|
|
|
467
541
|
_plot(
|
|
468
|
-
self.grid.ds,
|
|
469
542
|
field=field,
|
|
470
|
-
straddle=self.grid.straddle,
|
|
471
543
|
title=title,
|
|
472
|
-
kwargs=kwargs,
|
|
473
544
|
c="g",
|
|
545
|
+
kwargs=kwargs,
|
|
474
546
|
)
|
|
475
547
|
|
|
476
548
|
def save(
|
|
477
549
|
self,
|
|
478
550
|
filepath: Union[str, Path],
|
|
479
|
-
|
|
480
|
-
np_xi: int = None,
|
|
481
|
-
group: bool = False,
|
|
551
|
+
group: bool = True,
|
|
482
552
|
) -> None:
|
|
483
553
|
"""Save the surface forcing fields to one or more netCDF4 files.
|
|
484
554
|
|
|
485
|
-
This method saves the dataset
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
1. **Single File Mode (default)**:
|
|
489
|
-
- If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file.
|
|
490
|
-
- The file is named based on the `filepath`, with `.nc` automatically appended.
|
|
491
|
-
|
|
492
|
-
2. **Partitioned Mode**:
|
|
493
|
-
- If either `np_eta` or `np_xi` is specified, the dataset is partitioned into spatial tiles along the `eta` and `xi` axes.
|
|
494
|
-
- Each tile is saved as a separate netCDF4 file, and filenames are modified with an index (e.g., `"filepath_YYYYMM.0.nc"`, `"filepath_YYYYMM.1.nc"`).
|
|
495
|
-
|
|
496
|
-
Additionally, if `group` is set to `True`, the dataset is first grouped into temporal subsets, resulting in multiple grouped files before partitioning and saving.
|
|
555
|
+
This method saves the dataset to disk as either a single netCDF4 file or multiple files, depending on the `group` parameter.
|
|
556
|
+
If `group` is `True`, the dataset is divided into subsets (e.g., monthly or yearly) based on the temporal frequency
|
|
557
|
+
of the data, and each subset is saved to a separate file.
|
|
497
558
|
|
|
498
559
|
Parameters
|
|
499
560
|
----------
|
|
500
561
|
filepath : Union[str, Path]
|
|
501
|
-
The base path and filename for the output
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed.
|
|
506
|
-
np_xi : int, optional
|
|
507
|
-
The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed.
|
|
508
|
-
group: bool, optional
|
|
509
|
-
If `True`, groups the dataset into multiple files based on temporal data frequency. Defaults to `False`.
|
|
562
|
+
The base path and filename for the output file(s). If `group` is `True`, the filenames will include additional
|
|
563
|
+
time-based information (e.g., year or month) to distinguish the subsets.
|
|
564
|
+
group : bool, optional
|
|
565
|
+
Whether to divide the dataset into multiple files based on temporal frequency. Defaults to `True`.
|
|
510
566
|
|
|
511
567
|
Returns
|
|
512
568
|
-------
|
|
513
569
|
List[Path]
|
|
514
|
-
A list of Path objects
|
|
570
|
+
A list of `Path` objects representing the filenames of the saved file(s).
|
|
515
571
|
"""
|
|
516
572
|
|
|
517
573
|
# Ensure filepath is a Path object
|
|
@@ -521,12 +577,6 @@ class SurfaceForcing:
|
|
|
521
577
|
if filepath.suffix == ".nc":
|
|
522
578
|
filepath = filepath.with_suffix("")
|
|
523
579
|
|
|
524
|
-
if self.use_dask:
|
|
525
|
-
from dask.diagnostics import ProgressBar
|
|
526
|
-
|
|
527
|
-
with ProgressBar():
|
|
528
|
-
self.ds.load()
|
|
529
|
-
|
|
530
580
|
if group:
|
|
531
581
|
dataset_list, output_filenames = group_dataset(self.ds, str(filepath))
|
|
532
582
|
else:
|
|
@@ -534,7 +584,7 @@ class SurfaceForcing:
|
|
|
534
584
|
output_filenames = [str(filepath)]
|
|
535
585
|
|
|
536
586
|
saved_filenames = save_datasets(
|
|
537
|
-
dataset_list, output_filenames,
|
|
587
|
+
dataset_list, output_filenames, use_dask=self.use_dask
|
|
538
588
|
)
|
|
539
589
|
|
|
540
590
|
return saved_filenames
|