tfv-get-tools 0.2.1__tar.gz → 0.2.2__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.
Files changed (75) hide show
  1. {tfv_get_tools-0.2.1/src/tfv_get_tools.egg-info → tfv_get_tools-0.2.2}/PKG-INFO +6 -6
  2. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/README.md +5 -5
  3. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/pyproject.toml +1 -1
  4. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/_merger.py +9 -16
  5. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/era5.py +13 -7
  6. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2/src/tfv_get_tools.egg-info}/PKG-INFO +6 -6
  7. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_all_downloaders.py +41 -28
  8. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_mergers.py +36 -1
  9. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/LICENSE +0 -0
  10. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/setup.cfg +0 -0
  11. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/__init__.py +0 -0
  12. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/_standard_attrs.py +0 -0
  13. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/atmos.py +0 -0
  14. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/cli/_cli_base.py +0 -0
  15. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/cli/atmos_cli.py +0 -0
  16. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/cli/ocean_cli.py +0 -0
  17. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/cli/tide_cli.py +0 -0
  18. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/cli/wave_cli.py +0 -0
  19. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/fvc/__init__.py +0 -0
  20. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/fvc/_atmos.py +0 -0
  21. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/fvc/_fvc.py +0 -0
  22. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/fvc/_ocean.py +0 -0
  23. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/fvc/_tide.py +0 -0
  24. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/ocean.py +0 -0
  25. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/__init__.py +0 -0
  26. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/_custom_conversions.py +0 -0
  27. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/_downloader.py +0 -0
  28. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/_utilities.py +0 -0
  29. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/barra2.py +0 -0
  30. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/barra2_c2.yaml +0 -0
  31. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/barra2_r2.yaml +0 -0
  32. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/barra2_re2.yaml +0 -0
  33. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/cfsr.yaml +0 -0
  34. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/era5.yaml +0 -0
  35. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfgs/era5_gcp.yaml +0 -0
  36. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/cfsr.py +0 -0
  37. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/era5.py +0 -0
  38. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/atmos/era5_gcp.py +0 -0
  39. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_blk.yaml +0 -0
  40. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_glo.yaml +0 -0
  41. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/cfgs/copernicus_nws.yaml +0 -0
  42. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/cfgs/hycom.yaml +0 -0
  43. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/copernicus_ocean.py +0 -0
  44. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/ocean/hycom.py +0 -0
  45. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cawcr.py +0 -0
  46. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_10m.yaml +0 -0
  47. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/cawcr_aus_4m.yaml +0 -0
  48. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/cawcr_glob_24m.yaml +0 -0
  49. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_10m.yaml +0 -0
  50. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/cawcr_pac_4m.yaml +0 -0
  51. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/copernicus_glo.yaml +0 -0
  52. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/copernicus_nws.yaml +0 -0
  53. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/era5.yaml +0 -0
  54. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/cfgs/era5_gcp.yaml +0 -0
  55. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/copernicus_wave.py +0 -0
  56. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/providers/wave/era5_gcp.py +0 -0
  57. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/tide/__init__.py +0 -0
  58. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/tide/_nodestring.py +0 -0
  59. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/tide/_tidal_base.py +0 -0
  60. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/utilities/_tfv_bc.py +0 -0
  61. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/utilities/horizontal_padding.py +0 -0
  62. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/utilities/land_masking.py +0 -0
  63. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/utilities/parsers.py +0 -0
  64. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/utilities/warnings.py +0 -0
  65. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools/wave.py +0 -0
  66. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools.egg-info/SOURCES.txt +0 -0
  67. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools.egg-info/dependency_links.txt +0 -0
  68. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools.egg-info/entry_points.txt +0 -0
  69. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools.egg-info/requires.txt +0 -0
  70. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/src/tfv_get_tools.egg-info/top_level.txt +0 -0
  71. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_cli_get_atmos.py +0 -0
  72. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_downloader.py +0 -0
  73. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_era5_merger.py +0 -0
  74. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/tests/test_frontend_python_api.py +0 -0
  75. {tfv_get_tools-0.2.1 → tfv_get_tools-0.2.2}/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.1
3
+ Version: 0.2.2
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 [BMT](https://www.tuflow.com/), 2025
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 [BMT](https://www.tuflow.com/), 2025
233
+ Developed by [TUFLOW](https://www.tuflow.com/), 2025
234
234
 
235
235
  ## Project Status
236
236
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tfv_get_tools"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "Tool for downloading and processing data for TUFLOW FV modelling"
5
5
  authors = [
6
6
  { name = "Alex Waterhouse", email = "alex.waterhouse@apac.bmt.org" },
@@ -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
- start_time_strings = [x.stem.split("_")[-2] for x in file_list]
212
- end_time_strings = [x.stem.split("_")[-1] for x in file_list]
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.Timestamp(x, unit="h") for x in start_time_strings]
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.Timestamp(x, unit="h") for x in end_time_strings]
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.split("_")[-1] for x in file_list]
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.Timestamp(x, unit="h") for x in start_time_strings]
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.9h")
227
+ end_times = start_times + pd.Timedelta("23.99h")
235
228
  else:
236
229
  raise ValueError(f"Unknown download interval: {download_interval}")
237
230
 
@@ -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
- # For any other errors, show the original message if verbose
104
- if self.verbose:
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
 
@@ -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.1
3
+ Version: 0.2.2
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 [BMT](https://www.tuflow.com/), 2025
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
- result = DownloadOcean(
65
- start_date=self.start_date,
66
- end_date=self.end_date,
67
- xlims=self.xlims,
68
- ylims=self.ylims,
69
- source="COPERNICUS",
70
- model="GLO",
71
- out_path=temp_dir,
72
- TEST_MODE=self.test_mode,
73
- skip_check=self.skip_check,
74
- )
75
- assert result is not None
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
- result = DownloadWave(
81
- start_date=self.start_date,
82
- end_date=self.end_date,
83
- xlims=self.xlims,
84
- ylims=self.ylims,
85
- source="COPERNICUS",
86
- model="GLO",
87
- out_path=temp_dir,
88
- TEST_MODE=self.test_mode,
89
- skip_check=self.skip_check,
90
- )
91
- assert result is not None
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 test_time_filtering(self):
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