tfv-get-tools 0.2.1__tar.gz → 0.2.3__tar.gz
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.
- {tfv_get_tools-0.2.1/src/tfv_get_tools.egg-info → tfv_get_tools-0.2.3}/PKG-INFO +6 -6
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/README.md +5 -5
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/pyproject.toml +1 -1
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/_merger.py +9 -16
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/hycom.py +11 -5
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/era5.py +14 -8
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3/src/tfv_get_tools.egg-info}/PKG-INFO +6 -6
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_all_downloaders.py +41 -28
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_mergers.py +36 -1
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/LICENSE +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/setup.cfg +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/__init__.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/_standard_attrs.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/atmos.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/cli/_cli_base.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/cli/atmos_cli.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/cli/ocean_cli.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/cli/tide_cli.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/cli/wave_cli.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/fvc/__init__.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/fvc/_atmos.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/fvc/_fvc.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/fvc/_ocean.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/fvc/_tide.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/ocean.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/__init__.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/_custom_conversions.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/_downloader.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/_utilities.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/barra2.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_c2.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_r2.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_re2.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/cfsr.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/era5.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/era5_gcp.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfsr.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/era5.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/era5_gcp.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_blk.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_glo.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_nws.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/cfgs/hycom.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/copernicus_ocean.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cawcr.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_10m.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_4m.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_glob_24m.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_10m.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_4m.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/copernicus_glo.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/copernicus_nws.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/era5.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/era5_gcp.yaml +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/copernicus_wave.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/era5_gcp.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/tide/__init__.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/tide/_nodestring.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/tide/_tidal_base.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/_tfv_bc.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/horizontal_padding.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/land_masking.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/parsers.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/warnings.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/wave.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools.egg-info/SOURCES.txt +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools.egg-info/dependency_links.txt +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools.egg-info/entry_points.txt +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools.egg-info/requires.txt +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools.egg-info/top_level.txt +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_cli_get_atmos.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_downloader.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_era5_merger.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_frontend_python_api.py +0 -0
- {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/tests/test_tide_extraction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tfv_get_tools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Tool for downloading and processing data for TUFLOW FV modelling
|
|
5
5
|
Author-email: Alex Waterhouse <alex.waterhouse@apac.bmt.org>, Mitchell Smith <mitchell.smith@apac.bmt.org>, TUFLOW Support <support@tuflow.com>
|
|
6
6
|
License: MIT
|
|
@@ -60,22 +60,22 @@ TFV Get Tools is a Python package that simplifies the process of downloading and
|
|
|
60
60
|
### Supported Data Sources
|
|
61
61
|
|
|
62
62
|
**Atmospheric Data:**
|
|
63
|
-
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (Default - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
63
|
+
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (*Atmos Default* - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
64
64
|
- [NOAA CFSR](https://www.ncei.noaa.gov/data/climate-forecast-system/) (Climate Forecast System Reanalysis)
|
|
65
65
|
- [BARRA2](http://www.bom.gov.au/research/projects/reanalysis/) (Australian Bureau of Meteorology)
|
|
66
66
|
|
|
67
67
|
**Ocean Data:**
|
|
68
|
-
- [HYCOM](https://www.hycom.org/) (Naval Research Laboratory - Global Ocean Forecast System)
|
|
68
|
+
- [HYCOM](https://www.hycom.org/) (*Ocean Default* Naval Research Laboratory - Global Ocean Forecast System)
|
|
69
69
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS (registration required, see [Copernicus Marine Service](https://marine.copernicus.eu/))
|
|
70
70
|
|
|
71
71
|
**Wave Data:**
|
|
72
|
-
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
72
|
+
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (*Wave Default* glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
73
73
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS
|
|
74
74
|
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
75
75
|
|
|
76
76
|
**Tidal Data:**
|
|
77
77
|
- [FES2014](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2014)
|
|
78
|
-
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2022)
|
|
78
|
+
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (*Tide Default* AVISO+ Finite Element Solution 2022)
|
|
79
79
|
|
|
80
80
|
## Installation
|
|
81
81
|
|
|
@@ -276,7 +276,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
276
276
|
|
|
277
277
|
## Authors
|
|
278
278
|
|
|
279
|
-
Developed by [
|
|
279
|
+
Developed by [TUFLOW](https://www.tuflow.com/), 2025
|
|
280
280
|
|
|
281
281
|
## Project Status
|
|
282
282
|
|
|
@@ -14,22 +14,22 @@ TFV Get Tools is a Python package that simplifies the process of downloading and
|
|
|
14
14
|
### Supported Data Sources
|
|
15
15
|
|
|
16
16
|
**Atmospheric Data:**
|
|
17
|
-
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (Default - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
17
|
+
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (*Atmos Default* - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
18
18
|
- [NOAA CFSR](https://www.ncei.noaa.gov/data/climate-forecast-system/) (Climate Forecast System Reanalysis)
|
|
19
19
|
- [BARRA2](http://www.bom.gov.au/research/projects/reanalysis/) (Australian Bureau of Meteorology)
|
|
20
20
|
|
|
21
21
|
**Ocean Data:**
|
|
22
|
-
- [HYCOM](https://www.hycom.org/) (Naval Research Laboratory - Global Ocean Forecast System)
|
|
22
|
+
- [HYCOM](https://www.hycom.org/) (*Ocean Default* Naval Research Laboratory - Global Ocean Forecast System)
|
|
23
23
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS (registration required, see [Copernicus Marine Service](https://marine.copernicus.eu/))
|
|
24
24
|
|
|
25
25
|
**Wave Data:**
|
|
26
|
-
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
26
|
+
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (*Wave Default* glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
27
27
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS
|
|
28
28
|
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
29
29
|
|
|
30
30
|
**Tidal Data:**
|
|
31
31
|
- [FES2014](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2014)
|
|
32
|
-
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2022)
|
|
32
|
+
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (*Tide Default* AVISO+ Finite Element Solution 2022)
|
|
33
33
|
|
|
34
34
|
## Installation
|
|
35
35
|
|
|
@@ -230,7 +230,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
230
230
|
|
|
231
231
|
## Authors
|
|
232
232
|
|
|
233
|
-
Developed by [
|
|
233
|
+
Developed by [TUFLOW](https://www.tuflow.com/), 2025
|
|
234
234
|
|
|
235
235
|
## Project Status
|
|
236
236
|
|
|
@@ -208,30 +208,23 @@ class BaseMerger(ABC):
|
|
|
208
208
|
download_interval = self.cfg.get("_DOWNLOAD_INTERVAL", "monthly")
|
|
209
209
|
|
|
210
210
|
if download_interval == "monthly":
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
time_stings = [re.search(r'_(\d{8})_(\d{8})', x.stem) for x in file_list]
|
|
212
|
+
start_time_strings = [x.group(1) for x in time_stings]
|
|
213
|
+
end_time_strings = [x.group(2) for x in time_stings]
|
|
214
|
+
|
|
213
215
|
start_times = pd.DatetimeIndex(
|
|
214
|
-
[pd.
|
|
216
|
+
[pd.to_datetime(x, format="%Y%m%d") for x in start_time_strings]
|
|
215
217
|
)
|
|
216
218
|
end_times = pd.DatetimeIndex(
|
|
217
|
-
[pd.
|
|
219
|
+
[pd.to_datetime(x, format="%Y%m%d") for x in end_time_strings]
|
|
218
220
|
)
|
|
219
221
|
|
|
220
222
|
elif download_interval == "daily":
|
|
221
|
-
start_time_strings = [x.stem.
|
|
222
|
-
|
|
223
|
-
# Handle legacy HYCOM files
|
|
224
|
-
if start_time_strings and start_time_strings[0] == "0000":
|
|
225
|
-
if self.verbose:
|
|
226
|
-
print("WARNING: Detected legacy HYCOM files with time suffixes")
|
|
227
|
-
start_time_strings = [
|
|
228
|
-
x.name.split(".")[0].split("_")[-2] for x in file_list
|
|
229
|
-
]
|
|
230
|
-
|
|
223
|
+
start_time_strings = [re.search(r'_(\d{8})_', x.stem).group(1) for x in file_list]
|
|
231
224
|
start_times = pd.DatetimeIndex(
|
|
232
|
-
[pd.
|
|
225
|
+
[pd.to_datetime(x, format="%Y%m%d") for x in start_time_strings]
|
|
233
226
|
)
|
|
234
|
-
end_times = start_times + pd.Timedelta("23.
|
|
227
|
+
end_times = start_times + pd.Timedelta("23.99h")
|
|
235
228
|
else:
|
|
236
229
|
raise ValueError(f"Unknown download interval: {download_interval}")
|
|
237
230
|
|
|
@@ -516,7 +516,7 @@ class MergeHYCOM(BaseMerger):
|
|
|
516
516
|
|
|
517
517
|
if time_vars:
|
|
518
518
|
# Create single rolling object and apply to all variables
|
|
519
|
-
rolling_ds = ds[time_vars].rolling(time=25, center=True).reduce(np.nanmean)
|
|
519
|
+
rolling_ds = ds[time_vars].rolling(time=25, center=True, min_periods=1).reduce(np.nanmean)
|
|
520
520
|
|
|
521
521
|
for var_name in time_vars:
|
|
522
522
|
# Only replace post-cutoff values
|
|
@@ -572,10 +572,10 @@ class MergeHYCOM(BaseMerger):
|
|
|
572
572
|
if all_datasets and self._check_sub_daily_data(all_datasets[0]):
|
|
573
573
|
apply_tidal_filtering = True
|
|
574
574
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
575
|
+
print("Concatenating and interpolating xarray dataset")
|
|
576
|
+
if has_post_cutoff_data and apply_tidal_filtering:
|
|
577
|
+
print('... Dataset contains sub-daily data post-2024-08-10 (HYCOM ESPC-D-V02), applying tidal filtering using a simple 25h rolling mean.')
|
|
578
|
+
print('... Warning: Your dataset should be padded at least 1 full day either side before using in TUFLOW FV.')
|
|
579
579
|
|
|
580
580
|
# Merge variables for each start date group
|
|
581
581
|
merged_by_date = []
|
|
@@ -600,7 +600,13 @@ class MergeHYCOM(BaseMerger):
|
|
|
600
600
|
|
|
601
601
|
# Apply tidal filtering to the merged dataset if needed
|
|
602
602
|
if apply_tidal_filtering:
|
|
603
|
+
# Copy the original surface elevation data to a raw variable for later
|
|
604
|
+
raw_surf_el = merged['surf_el'].copy()
|
|
603
605
|
merged = self._apply_tidal_filtering(merged)
|
|
606
|
+
|
|
607
|
+
# Copy original surface elevation
|
|
608
|
+
merged['raw_surf_el'] = raw_surf_el
|
|
609
|
+
merged['raw_surf_el'].attrs['note'] = 'Original HYCOM water-level containing tides after 2024-08-10'
|
|
604
610
|
|
|
605
611
|
# Final cleanup
|
|
606
612
|
merged = merged.rename({'lon': 'longitude', 'lat': 'latitude'})
|
|
@@ -99,13 +99,19 @@ class DownloadERA5Wave(BaseDownloader):
|
|
|
99
99
|
print("You can find your key at: https://cds.climate.copernicus.eu/user/")
|
|
100
100
|
print("="*60)
|
|
101
101
|
|
|
102
|
+
elif "cds-beta.climate.copernicus.eu" in error_msg:
|
|
103
|
+
print("\n" + "="*60)
|
|
104
|
+
print("CDS API AUTHENTICATION ERROR")
|
|
105
|
+
print("="*60)
|
|
106
|
+
print("Your CDS API key appears to be invalid.")
|
|
107
|
+
print("This is likely due to an update by the Copernicus Climate Data Store.")
|
|
108
|
+
print("Please check your .cdsapirc file and ensure your API key is correct.")
|
|
109
|
+
print("You can find your key at: https://cds.climate.copernicus.eu/user/")
|
|
110
|
+
print("="*60)
|
|
111
|
+
|
|
102
112
|
else:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
print(f"Failed to download via CDS API: {e}")
|
|
106
|
-
else:
|
|
107
|
-
# Always show some info for unhandled errors
|
|
108
|
-
print(f"\nCDS API Error: {e}")
|
|
113
|
+
print(f"Failed to download via CDS API: {e}")
|
|
114
|
+
|
|
109
115
|
|
|
110
116
|
return False
|
|
111
117
|
|
|
@@ -141,7 +147,7 @@ class DownloadERA5Wave(BaseDownloader):
|
|
|
141
147
|
raise ValueError("No NetCDF files found in zip archive")
|
|
142
148
|
|
|
143
149
|
# Combine all datasets
|
|
144
|
-
ds = xr.merge(datasets)
|
|
150
|
+
ds = xr.merge(datasets, compat='override')
|
|
145
151
|
ds.to_netcdf(file_path_out)
|
|
146
152
|
|
|
147
153
|
# Delete the zip file
|
|
@@ -229,4 +235,4 @@ class MergeERA5Wave(BaseMerger):
|
|
|
229
235
|
if 'latitude' in merged.coords:
|
|
230
236
|
merged = merged.sortby("latitude")
|
|
231
237
|
|
|
232
|
-
return merged, skipped_files
|
|
238
|
+
return merged, skipped_files
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tfv_get_tools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Tool for downloading and processing data for TUFLOW FV modelling
|
|
5
5
|
Author-email: Alex Waterhouse <alex.waterhouse@apac.bmt.org>, Mitchell Smith <mitchell.smith@apac.bmt.org>, TUFLOW Support <support@tuflow.com>
|
|
6
6
|
License: MIT
|
|
@@ -60,22 +60,22 @@ TFV Get Tools is a Python package that simplifies the process of downloading and
|
|
|
60
60
|
### Supported Data Sources
|
|
61
61
|
|
|
62
62
|
**Atmospheric Data:**
|
|
63
|
-
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (Default - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
63
|
+
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (*Atmos Default* - registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
64
64
|
- [NOAA CFSR](https://www.ncei.noaa.gov/data/climate-forecast-system/) (Climate Forecast System Reanalysis)
|
|
65
65
|
- [BARRA2](http://www.bom.gov.au/research/projects/reanalysis/) (Australian Bureau of Meteorology)
|
|
66
66
|
|
|
67
67
|
**Ocean Data:**
|
|
68
|
-
- [HYCOM](https://www.hycom.org/) (Naval Research Laboratory - Global Ocean Forecast System)
|
|
68
|
+
- [HYCOM](https://www.hycom.org/) (*Ocean Default* Naval Research Laboratory - Global Ocean Forecast System)
|
|
69
69
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS (registration required, see [Copernicus Marine Service](https://marine.copernicus.eu/))
|
|
70
70
|
|
|
71
71
|
**Wave Data:**
|
|
72
|
-
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
72
|
+
- [CSIRO CAWCR](https://data.csiro.au/collection/csiro:39819) (*Wave Default* glob_24m, aus_10m, aus_4m, pac_10m, pac_4m)
|
|
73
73
|
- [Copernicus Marine](https://marine.copernicus.eu/) Global and NWS
|
|
74
74
|
- [ECMWF ERA5](https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5) (registration required, see [CDS API](https://cds.climate.copernicus.eu/api-how-to))
|
|
75
75
|
|
|
76
76
|
**Tidal Data:**
|
|
77
77
|
- [FES2014](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2014)
|
|
78
|
-
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (AVISO+ Finite Element Solution 2022)
|
|
78
|
+
- [FES2022](https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html) (*Tide Default* AVISO+ Finite Element Solution 2022)
|
|
79
79
|
|
|
80
80
|
## Installation
|
|
81
81
|
|
|
@@ -276,7 +276,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
276
276
|
|
|
277
277
|
## Authors
|
|
278
278
|
|
|
279
|
-
Developed by [
|
|
279
|
+
Developed by [TUFLOW](https://www.tuflow.com/), 2025
|
|
280
280
|
|
|
281
281
|
## Project Status
|
|
282
282
|
|
|
@@ -9,11 +9,16 @@ from tfv_get_tools import DownloadAtmos, DownloadOcean, DownloadWave
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
# Loopy test :) Add new sources here
|
|
12
|
+
# Turned off Copernicus because of login checks
|
|
13
|
+
# We could mock this properly but I think it
|
|
14
|
+
# is low value...
|
|
15
|
+
# There is a test for login failure low which will only trigger
|
|
16
|
+
# if it asks for stdin user/password, which means it is working
|
|
12
17
|
@pytest.mark.parametrize(
|
|
13
18
|
"source,downloader_class,model",
|
|
14
19
|
[
|
|
15
|
-
("COPERNICUS", DownloadOcean, "GLO"),
|
|
16
|
-
("COPERNICUS", DownloadWave, "GLO"),
|
|
20
|
+
# ("COPERNICUS", DownloadOcean, "GLO"),
|
|
21
|
+
# ("COPERNICUS", DownloadWave, "GLO"),
|
|
17
22
|
("HYCOM", DownloadOcean, None),
|
|
18
23
|
("CAWCR", DownloadWave, "glob_24m"),
|
|
19
24
|
("CAWCR", DownloadWave, "aus_10m"),
|
|
@@ -59,36 +64,44 @@ class TestDownloaderIntegration:
|
|
|
59
64
|
skip_check = True
|
|
60
65
|
|
|
61
66
|
def test_copernicus_ocean_glo(self):
|
|
62
|
-
"""Test COPERNICUS ocean downloader with GLO model.
|
|
67
|
+
"""Test COPERNICUS ocean downloader with GLO model.
|
|
68
|
+
These could be better - I am testing that copernicus kicks off ok
|
|
69
|
+
and that it triggers a manual user login via terminal"""
|
|
63
70
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
|
|
72
|
+
with pytest.raises(OSError,
|
|
73
|
+
match="reading from stdin"):
|
|
74
|
+
result = DownloadOcean(
|
|
75
|
+
start_date=self.start_date,
|
|
76
|
+
end_date=self.end_date,
|
|
77
|
+
xlims=self.xlims,
|
|
78
|
+
ylims=self.ylims,
|
|
79
|
+
source="COPERNICUS",
|
|
80
|
+
model="GLO",
|
|
81
|
+
out_path=temp_dir,
|
|
82
|
+
TEST_MODE=self.test_mode,
|
|
83
|
+
skip_check=self.skip_check,
|
|
84
|
+
)
|
|
85
|
+
|
|
76
86
|
|
|
77
87
|
def test_copernicus_wave_glo(self):
|
|
78
|
-
"""Test COPERNICUS wave downloader with GLO model.
|
|
88
|
+
"""Test COPERNICUS wave downloader with GLO model.
|
|
89
|
+
These could be better - I am testing that copernicus kicks off ok
|
|
90
|
+
and that it triggers a manual user login via terminal"""
|
|
79
91
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
with pytest.raises(OSError,
|
|
93
|
+
match="reading from stdin"):
|
|
94
|
+
result = DownloadWave(
|
|
95
|
+
start_date=self.start_date,
|
|
96
|
+
end_date=self.end_date,
|
|
97
|
+
xlims=self.xlims,
|
|
98
|
+
ylims=self.ylims,
|
|
99
|
+
source="COPERNICUS",
|
|
100
|
+
model="GLO",
|
|
101
|
+
out_path=temp_dir,
|
|
102
|
+
TEST_MODE=self.test_mode,
|
|
103
|
+
skip_check=self.skip_check,
|
|
104
|
+
)
|
|
92
105
|
|
|
93
106
|
def test_hycom_ocean(self):
|
|
94
107
|
"""Test HYCOM ocean downloader."""
|
|
@@ -378,7 +378,7 @@ class TestFileHandling:
|
|
|
378
378
|
assert "RANDOM_FILE.nc" not in era5_files
|
|
379
379
|
assert "ERA5_WAVE_20220101_20220131.nc" not in era5_files
|
|
380
380
|
|
|
381
|
-
def
|
|
381
|
+
def test_time_filtering_simple_ERA5(self):
|
|
382
382
|
"""Test filtering files by time range."""
|
|
383
383
|
# Create files with different dates
|
|
384
384
|
test_files = [
|
|
@@ -408,6 +408,41 @@ class TestFileHandling:
|
|
|
408
408
|
assert "ERA5_ATMOS_20220201_20220228.nc" in filtered_files
|
|
409
409
|
# Should exclude March file
|
|
410
410
|
assert "ERA5_ATMOS_20220301_20220331.nc" not in filtered_files
|
|
411
|
+
|
|
412
|
+
def test_time_filtering_painful_HYCOM(self):
|
|
413
|
+
"""Test filtering files by time range."""
|
|
414
|
+
# Create files with different dates
|
|
415
|
+
test_files = [
|
|
416
|
+
"HYCOM_OCEAN_20220101_03h.nc",
|
|
417
|
+
"HYCOM_OCEAN_20220102_03h_somedbase.nc",
|
|
418
|
+
"A_LONG_PREFIX_BOUND_TO_GET_YA_HYCOM_OCEAN_20220103_03h_somedbase.nc",
|
|
419
|
+
"KEEP_ME_HYCOM_OCEAN_20210101_03h.nc",
|
|
420
|
+
"EXCLUDE_ME_HYCOM_OCEAN_20230101_03h.nc",
|
|
421
|
+
"WHY_DID_I_EVER_ALLOW_SUCH_FLEXIBILITY_HYCOM_OCEAN_20220301_03h.nc",
|
|
422
|
+
]
|
|
423
|
+
|
|
424
|
+
for filename in test_files:
|
|
425
|
+
(self.in_path / filename).touch()
|
|
426
|
+
|
|
427
|
+
# Test filtering with time constraints
|
|
428
|
+
merger = MergeHYCOM(
|
|
429
|
+
in_path=self.in_path,
|
|
430
|
+
out_path=self.out_path,
|
|
431
|
+
time_start="2021-01-01", # Keep em all except the EXCLUDE_ME one
|
|
432
|
+
time_end="2022-09-01",
|
|
433
|
+
execute=False,
|
|
434
|
+
verbose=False
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
files = merger.get_file_list()
|
|
438
|
+
filtered_files = [f.name for f in files]
|
|
439
|
+
|
|
440
|
+
# Should include Jan and Feb files
|
|
441
|
+
assert "KEEP_ME_HYCOM_OCEAN_20210101_03h.nc" in filtered_files
|
|
442
|
+
|
|
443
|
+
# Should exclude March file
|
|
444
|
+
assert "EXCLUDE_ME_HYCOM_OCEAN_20230101_03h.nc" not in filtered_files
|
|
445
|
+
|
|
411
446
|
|
|
412
447
|
def test_no_files_found_error(self):
|
|
413
448
|
"""Test error handling when no files match pattern."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/_custom_conversions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_c2.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_r2.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/barra2_re2.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/cfsr.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/era5.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/atmos/cfgs/era5_gcp.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/cfgs/hycom.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/ocean/copernicus_ocean.py
RENAMED
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_10m.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_4m.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_10m.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_4m.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/cfgs/era5_gcp.yaml
RENAMED
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/providers/wave/copernicus_wave.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tfv_get_tools-0.2.1 → tfv_get_tools-0.2.3}/src/tfv_get_tools/utilities/horizontal_padding.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|