eo-tides 0.0.18__py3-none-any.whl → 0.0.20__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.
- eo_tides/model.py +144 -77
- {eo_tides-0.0.18.dist-info → eo_tides-0.0.20.dist-info}/METADATA +1 -1
- eo_tides-0.0.20.dist-info/RECORD +10 -0
- eo_tides-0.0.18.dist-info/RECORD +0 -10
- {eo_tides-0.0.18.dist-info → eo_tides-0.0.20.dist-info}/LICENSE +0 -0
- {eo_tides-0.0.18.dist-info → eo_tides-0.0.20.dist-info}/WHEEL +0 -0
- {eo_tides-0.0.18.dist-info → eo_tides-0.0.20.dist-info}/top_level.txt +0 -0
eo_tides/model.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
import pathlib
|
3
|
+
import warnings
|
3
4
|
from concurrent.futures import ProcessPoolExecutor
|
4
5
|
from functools import partial
|
5
6
|
|
@@ -9,11 +10,111 @@ import odc.geo.xr
|
|
9
10
|
import pandas as pd
|
10
11
|
import pyproj
|
11
12
|
import pyTMD
|
13
|
+
from pyTMD.io.model import load_database, model
|
12
14
|
from tqdm import tqdm
|
13
15
|
|
14
16
|
from eo_tides.utils import idw
|
15
17
|
|
16
18
|
|
19
|
+
def _set_directory(directory):
|
20
|
+
"""
|
21
|
+
Set tide modelling files directory. If no custom
|
22
|
+
path is provided, try global environmental variable
|
23
|
+
instead.
|
24
|
+
"""
|
25
|
+
if directory is None:
|
26
|
+
if "EO_TIDES_TIDE_MODELS" in os.environ:
|
27
|
+
directory = os.environ["EO_TIDES_TIDE_MODELS"]
|
28
|
+
else:
|
29
|
+
raise Exception(
|
30
|
+
"No tide model directory provided via `directory`, and/or no "
|
31
|
+
"`EO_TIDES_TIDE_MODELS` environment variable found. "
|
32
|
+
"Please provide a valid path to your tide model directory."
|
33
|
+
)
|
34
|
+
|
35
|
+
# Verify path exists
|
36
|
+
directory = pathlib.Path(directory).expanduser()
|
37
|
+
if not directory.exists():
|
38
|
+
raise FileNotFoundError(f"No valid tide model directory found at path `{directory}`")
|
39
|
+
else:
|
40
|
+
return directory
|
41
|
+
|
42
|
+
|
43
|
+
def list_models(directory=None, show_available=True, show_supported=True, raise_error=False):
|
44
|
+
"""
|
45
|
+
List all tide models available for tide modelling, and
|
46
|
+
all models supported by `eo-tides` and `pyTMD`.
|
47
|
+
|
48
|
+
This function scans the specified tide model directory
|
49
|
+
and returns a list of models that are available in the
|
50
|
+
directory as well as the full list of all supported models.
|
51
|
+
|
52
|
+
For instructions on setting up tide models, see:
|
53
|
+
<https://geoscienceaustralia.github.io/eo-tides/setup/>
|
54
|
+
|
55
|
+
Parameters
|
56
|
+
----------
|
57
|
+
directory : string, optional
|
58
|
+
The directory containing tide model data files. If no path is
|
59
|
+
provided, this will default to the environment variable
|
60
|
+
`EO_TIDES_TIDE_MODELS` if set, or raise an error if not.
|
61
|
+
Tide modelling files should be stored in sub-folders for each
|
62
|
+
model that match the structure required by `pyTMD`
|
63
|
+
(<https://geoscienceaustralia.github.io/eo-tides/setup/>).
|
64
|
+
show_available : bool, optional
|
65
|
+
Whether to print a list of locally available models.
|
66
|
+
show_supported : bool, optional
|
67
|
+
Whether to print a list of all supported models, in
|
68
|
+
addition to models available locally.
|
69
|
+
|
70
|
+
Returns
|
71
|
+
-------
|
72
|
+
available_models : list
|
73
|
+
A list of alltide models available within `directory`.
|
74
|
+
supported_models : list
|
75
|
+
A list of all tide models supported by `eo-tides`.
|
76
|
+
"""
|
77
|
+
# Set tide modelling files directory. If no custom path is
|
78
|
+
# provided, try global environment variable.
|
79
|
+
directory = _set_directory(directory)
|
80
|
+
|
81
|
+
# Get full list of supported models from pyTMD database
|
82
|
+
supported_models = list(load_database()["elevation"].keys())
|
83
|
+
|
84
|
+
# Print list of supported models, marking available and
|
85
|
+
# unavailable models and appending available to list
|
86
|
+
if show_available or show_supported:
|
87
|
+
print(f"Tide models available in `{directory}`:")
|
88
|
+
available_models = []
|
89
|
+
for m in supported_models:
|
90
|
+
try:
|
91
|
+
model(directory=directory).elevation(m=m)
|
92
|
+
if show_available:
|
93
|
+
# Mark available models with a green tick
|
94
|
+
print(f" ✅ {m}")
|
95
|
+
available_models.append(m)
|
96
|
+
except:
|
97
|
+
if show_supported:
|
98
|
+
# Mark unavailable models with a red cross
|
99
|
+
print(f" ❌ {m}")
|
100
|
+
|
101
|
+
# Raise error or warning if no models are available
|
102
|
+
if not available_models:
|
103
|
+
warning_text = (
|
104
|
+
f"No valid tide models are available in `{directory}`. "
|
105
|
+
"Verify that you have provided the correct `directory` path, "
|
106
|
+
"or set the `EO_TIDES_TIDE_MODELS` environment variable "
|
107
|
+
"to point to the location of your tide model directory."
|
108
|
+
)
|
109
|
+
if raise_error:
|
110
|
+
raise Exception(warning_text)
|
111
|
+
else:
|
112
|
+
warnings.warn(warning_text, UserWarning)
|
113
|
+
|
114
|
+
# Return list of available and supported models
|
115
|
+
return available_models, supported_models
|
116
|
+
|
117
|
+
|
17
118
|
def _model_tides(
|
18
119
|
model,
|
19
120
|
x,
|
@@ -32,34 +133,7 @@ def _model_tides(
|
|
32
133
|
extraction of tide modelling constituents and tide modelling using
|
33
134
|
`pyTMD`.
|
34
135
|
"""
|
35
|
-
#
|
36
|
-
# import pyTMD.io
|
37
|
-
# import pyTMD.io.model
|
38
|
-
# import pyTMD.predict
|
39
|
-
# import pyTMD.spatial
|
40
|
-
# import pyTMD.time
|
41
|
-
# import pyTMD.utilities
|
42
|
-
|
43
|
-
# Get parameters for tide model; use custom definition file for
|
44
|
-
# FES2012 (leave this as an undocumented feature for now)
|
45
|
-
# if model == "FES2012":
|
46
|
-
# pytmd_model = pyTMD.io.model(directory).from_file(
|
47
|
-
# directory / "model_FES2012.def"
|
48
|
-
# )
|
49
|
-
# elif model == "TPXO8-atlas-v1":
|
50
|
-
# pytmd_model = pyTMD.io.model(directory).from_file(directory / "model_TPXO8.def")
|
51
|
-
# else:
|
52
|
-
# pytmd_model = pyTMD.io.model(
|
53
|
-
# directory, format="netcdf", compressed=False
|
54
|
-
# ).elevation(model)
|
55
|
-
|
56
|
-
# if model in NONSTANDARD_MODELS:
|
57
|
-
# model_params = NONSTANDARD_MODELS[model]
|
58
|
-
# model_params_bytes = io.BytesIO(json.dumps(model_params).encode("utf-8"))
|
59
|
-
# pytmd_model = pyTMD.io.model(directory).from_file(definition_file=model_params_bytes)
|
60
|
-
|
61
|
-
# else:
|
62
|
-
|
136
|
+
# Obtain model details
|
63
137
|
pytmd_model = pyTMD.io.model(directory).elevation(model)
|
64
138
|
|
65
139
|
# Convert x, y to latitude/longitude
|
@@ -411,11 +485,12 @@ def model_tides(
|
|
411
485
|
|
412
486
|
This function is parallelised to improve performance, and
|
413
487
|
supports all tidal models supported by `pyTMD`, including:
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
488
|
+
|
489
|
+
- Empirical Ocean Tide model (`EOT20`)
|
490
|
+
- Finite Element Solution tide models (`FES2022`, `FES2014`, `FES2012`)
|
491
|
+
- TOPEX/POSEIDON global tide models (`TPXO10`, `TPXO9`, `TPXO8`)
|
492
|
+
- Global Ocean Tide models (`GOT5.6`, `GOT5.5`, `GOT4.10`, `GOT4.8`, `GOT4.7`)
|
493
|
+
- Hamburg direct data Assimilation Methods for Tides models (`HAMTIDE11`)
|
419
494
|
|
420
495
|
This function requires access to tide model data files.
|
421
496
|
These should be placed in a folder with subfolders matching
|
@@ -441,11 +516,11 @@ def model_tides(
|
|
441
516
|
model : string, optional
|
442
517
|
The tide model used to model tides. Options include:
|
443
518
|
|
444
|
-
- "
|
519
|
+
- "EOT20"
|
520
|
+
- "FES2014"
|
445
521
|
- "FES2022"
|
446
522
|
- "TPXO9-atlas-v5"
|
447
523
|
- "TPXO8-atlas"
|
448
|
-
- "EOT20"
|
449
524
|
- "HAMTIDE11"
|
450
525
|
- "GOT4.10"
|
451
526
|
- "ensemble" (advanced ensemble tide model functionality;
|
@@ -453,7 +528,7 @@ def model_tides(
|
|
453
528
|
directory : string, optional
|
454
529
|
The directory containing tide model data files. If no path is
|
455
530
|
provided, this will default to the environment variable
|
456
|
-
`EO_TIDES_TIDE_MODELS` if set,
|
531
|
+
`EO_TIDES_TIDE_MODELS` if set, or raise an error if not.
|
457
532
|
Tide modelling files should be stored in sub-folders for each
|
458
533
|
model that match the structure provided by `pyTMD`.
|
459
534
|
|
@@ -539,23 +614,6 @@ def model_tides(
|
|
539
614
|
A dataframe containing modelled tide heights.
|
540
615
|
|
541
616
|
"""
|
542
|
-
# Set tide modelling files directory. If no custom path is provided,
|
543
|
-
# first try global environmental var, then "/var/share/tide_models"
|
544
|
-
if directory is None:
|
545
|
-
if "EO_TIDES_TIDE_MODELS" in os.environ:
|
546
|
-
directory = os.environ["EO_TIDES_TIDE_MODELS"]
|
547
|
-
else:
|
548
|
-
directory = "/var/share/tide_models"
|
549
|
-
|
550
|
-
# Verify path exists
|
551
|
-
directory = pathlib.Path(directory).expanduser()
|
552
|
-
if not directory.exists():
|
553
|
-
raise FileNotFoundError("Invalid tide directory")
|
554
|
-
|
555
|
-
# If time passed as a single Timestamp, convert to datetime64
|
556
|
-
if isinstance(time, pd.Timestamp):
|
557
|
-
time = time.to_datetime64()
|
558
|
-
|
559
617
|
# Turn inputs into arrays for consistent handling
|
560
618
|
models_requested = np.atleast_1d(model)
|
561
619
|
x = np.atleast_1d(x)
|
@@ -581,32 +639,41 @@ def model_tides(
|
|
581
639
|
"you intended to model multiple timesteps at each point."
|
582
640
|
)
|
583
641
|
|
584
|
-
#
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
# Advanced ensemble model functionality
|
602
|
-
"ensemble",
|
603
|
-
]
|
642
|
+
# If time passed as a single Timestamp, convert to datetime64
|
643
|
+
if isinstance(time, pd.Timestamp):
|
644
|
+
time = time.to_datetime64()
|
645
|
+
|
646
|
+
# Set tide modelling files directory. If no custom path is
|
647
|
+
# provided, try global environment variable.
|
648
|
+
directory = _set_directory(directory)
|
649
|
+
|
650
|
+
# Get full list of supported models from pyTMD database;
|
651
|
+
# add ensemble option to list of models
|
652
|
+
available_models, valid_models = list_models(
|
653
|
+
directory, show_available=False, show_supported=False, raise_error=True
|
654
|
+
)
|
655
|
+
available_models = available_models + ["ensemble"]
|
656
|
+
valid_models = valid_models + ["ensemble"]
|
657
|
+
|
658
|
+
# Error if any models are not supported
|
604
659
|
if not all(m in valid_models for m in models_requested):
|
605
|
-
|
606
|
-
f"One or more of the models
|
607
|
-
f"
|
608
|
-
|
660
|
+
error_text = (
|
661
|
+
f"One or more of the requested models are not valid:\n"
|
662
|
+
f"{models_requested}\n\n"
|
663
|
+
"The following models are supported:\n"
|
664
|
+
f"{valid_models}"
|
665
|
+
)
|
666
|
+
raise ValueError(error_text)
|
667
|
+
|
668
|
+
# Error if any models are not available in `directory`
|
669
|
+
if not all(m in available_models for m in models_requested):
|
670
|
+
error_text = (
|
671
|
+
f"One or more of the requested models are valid, but not available in `{directory}`:\n"
|
672
|
+
f"{models_requested}\n\n"
|
673
|
+
f"The following models are available in `{directory}`:\n"
|
674
|
+
f"{available_models}"
|
609
675
|
)
|
676
|
+
raise ValueError(error_text)
|
610
677
|
|
611
678
|
# If ensemble modelling is requested, use a custom list of models
|
612
679
|
# for subsequent processing
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: eo-tides
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.20
|
4
4
|
Summary: Tide modelling tools for large-scale satellite earth observation analysis
|
5
5
|
Author-email: Robbi Bishop-Taylor <Robbi.BishopTaylor@ga.gov.au>
|
6
6
|
Project-URL: Homepage, https://GeoscienceAustralia.github.io/eo-tides/
|
@@ -0,0 +1,10 @@
|
|
1
|
+
eo_tides/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
eo_tides/model.py,sha256=wo2bsWEefpTFd3KrkzZelIU4FV_noCNJjMQs2arwypk,46021
|
3
|
+
eo_tides/stats.py,sha256=Lzo46pWUhox3ZUnMLtyLzqZ9FrCNG6nJ6iS5IpqEsy8,158
|
4
|
+
eo_tides/utils.py,sha256=l9VXJawQzaRBYaFMsP8VBeaN5VA3rFDdzcvF7Rk04Vc,5620
|
5
|
+
eo_tides/validation.py,sha256=kpYGHOeK-YP11c3tHt9l5_8IvOHF1SAJP79PXA7i-Vs,11434
|
6
|
+
eo_tides-0.0.20.dist-info/LICENSE,sha256=NYULqbFuDRV6CysPbkR2WZk863YwwHeftBtnsb4cWf8,1077
|
7
|
+
eo_tides-0.0.20.dist-info/METADATA,sha256=_Ns8em48OsUfgl97Rw4hSPXPqfJV9FelTtq25qcb4ag,5335
|
8
|
+
eo_tides-0.0.20.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
9
|
+
eo_tides-0.0.20.dist-info/top_level.txt,sha256=lXZDUUM1DlLdKWHRn8zdmtW8Rx-eQOIWVvt0b8VGiyQ,9
|
10
|
+
eo_tides-0.0.20.dist-info/RECORD,,
|
eo_tides-0.0.18.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
eo_tides/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
eo_tides/model.py,sha256=5teDNCgtqRyp0vJHhXMdPtZYdaKzXcAo-a9Cum46Jgg,43305
|
3
|
-
eo_tides/stats.py,sha256=Lzo46pWUhox3ZUnMLtyLzqZ9FrCNG6nJ6iS5IpqEsy8,158
|
4
|
-
eo_tides/utils.py,sha256=l9VXJawQzaRBYaFMsP8VBeaN5VA3rFDdzcvF7Rk04Vc,5620
|
5
|
-
eo_tides/validation.py,sha256=kpYGHOeK-YP11c3tHt9l5_8IvOHF1SAJP79PXA7i-Vs,11434
|
6
|
-
eo_tides-0.0.18.dist-info/LICENSE,sha256=NYULqbFuDRV6CysPbkR2WZk863YwwHeftBtnsb4cWf8,1077
|
7
|
-
eo_tides-0.0.18.dist-info/METADATA,sha256=WLxfpg2EhN7Ly9GbNhLLFJVa2LiuO3NHckIcmjY2pqE,5335
|
8
|
-
eo_tides-0.0.18.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
9
|
-
eo_tides-0.0.18.dist-info/top_level.txt,sha256=lXZDUUM1DlLdKWHRn8zdmtW8Rx-eQOIWVvt0b8VGiyQ,9
|
10
|
-
eo_tides-0.0.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|