tipmip-toad 1.0.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.
- tipmip_toad-1.0.2/LICENSE.txt +11 -0
- tipmip_toad-1.0.2/PKG-INFO +157 -0
- tipmip_toad-1.0.2/README.md +112 -0
- tipmip_toad-1.0.2/docs/source/conf.py +178 -0
- tipmip_toad-1.0.2/pyproject.toml +121 -0
- tipmip_toad-1.0.2/setup.cfg +4 -0
- tipmip_toad-1.0.2/tests/aggregation/test_cluster_consensus.py +217 -0
- tipmip_toad-1.0.2/tests/clustering/test_cluster_optimization.py +30 -0
- tipmip_toad-1.0.2/tests/clustering/test_healpix_hdbscan.py +63 -0
- tipmip_toad-1.0.2/tests/clustering/test_irregular_grid.py +67 -0
- tipmip_toad-1.0.2/tests/shifts_detection/test_asdetect.py +224 -0
- tipmip_toad-1.0.2/tipmip_toad.egg-info/PKG-INFO +157 -0
- tipmip_toad-1.0.2/tipmip_toad.egg-info/SOURCES.txt +40 -0
- tipmip_toad-1.0.2/tipmip_toad.egg-info/dependency_links.txt +1 -0
- tipmip_toad-1.0.2/tipmip_toad.egg-info/requires.txt +21 -0
- tipmip_toad-1.0.2/tipmip_toad.egg-info/top_level.txt +5 -0
- tipmip_toad-1.0.2/toad/__init__.py +22 -0
- tipmip_toad-1.0.2/toad/_version.py +1 -0
- tipmip_toad-1.0.2/toad/_warnings.py +16 -0
- tipmip_toad-1.0.2/toad/clustering/__init__.py +541 -0
- tipmip_toad-1.0.2/toad/clustering/optimizing.py +290 -0
- tipmip_toad-1.0.2/toad/core.py +1458 -0
- tipmip_toad-1.0.2/toad/plotting/__init__.py +2671 -0
- tipmip_toad-1.0.2/toad/postprocessing/__init__.py +4 -0
- tipmip_toad-1.0.2/toad/postprocessing/aggregation.py +668 -0
- tipmip_toad-1.0.2/toad/postprocessing/stats/__init__.py +35 -0
- tipmip_toad-1.0.2/toad/postprocessing/stats/general.py +539 -0
- tipmip_toad-1.0.2/toad/postprocessing/stats/space.py +196 -0
- tipmip_toad-1.0.2/toad/postprocessing/stats/time.py +365 -0
- tipmip_toad-1.0.2/toad/preprocessing.py +97 -0
- tipmip_toad-1.0.2/toad/py.typed +0 -0
- tipmip_toad-1.0.2/toad/regridding/__init__.py +10 -0
- tipmip_toad-1.0.2/toad/regridding/base.py +74 -0
- tipmip_toad-1.0.2/toad/regridding/healpix.py +163 -0
- tipmip_toad-1.0.2/toad/shifts/__init__.py +332 -0
- tipmip_toad-1.0.2/toad/shifts/methods/__init__.py +3 -0
- tipmip_toad-1.0.2/toad/shifts/methods/asdetect.py +530 -0
- tipmip_toad-1.0.2/toad/shifts/methods/base.py +24 -0
- tipmip_toad-1.0.2/toad/utils/__init__.py +402 -0
- tipmip_toad-1.0.2/toad/utils/cluster_consensus_utils.py +457 -0
- tipmip_toad-1.0.2/toad/utils/shift_selection_utils.py +253 -0
- tipmip_toad-1.0.2/toad/utils/synthetic_data.py +207 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright 2026 TOAD Developers
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tipmip-toad
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Tipping and Other Abrupt events Detector
|
|
5
|
+
Author-email: Jakob Harteg <jakob.harteg@pik-potsdam.de>, Lukas Roehrich <lukas.roehrich@pik-potsdam.de>, Sina Loriani <sina.loriani@pik-potsdam.de>
|
|
6
|
+
Maintainer-email: Jakob Harteg <jakob.harteg@pik-potsdam.de>
|
|
7
|
+
License-Expression: BSD-2-Clause
|
|
8
|
+
Project-URL: Homepage, https://tipmip.pik-potsdam.de/
|
|
9
|
+
Project-URL: Repository, https://github.com/tipmip-methods/toad
|
|
10
|
+
Keywords: tipping,tipping points,climate,abrupt shifts,earth system
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Oceanography
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE.txt
|
|
24
|
+
Requires-Dist: numpy<2.3.0,>=2.2.0
|
|
25
|
+
Requires-Dist: matplotlib
|
|
26
|
+
Requires-Dist: scipy<1.17.0,>=1.15.0
|
|
27
|
+
Requires-Dist: scikit-learn<1.8.0,>=1.7.1
|
|
28
|
+
Requires-Dist: xarray
|
|
29
|
+
Requires-Dist: netcdf4
|
|
30
|
+
Requires-Dist: cartopy
|
|
31
|
+
Requires-Dist: pandas
|
|
32
|
+
Requires-Dist: numba
|
|
33
|
+
Requires-Dist: healpix
|
|
34
|
+
Requires-Dist: optuna
|
|
35
|
+
Requires-Dist: cftime
|
|
36
|
+
Requires-Dist: joblib
|
|
37
|
+
Requires-Dist: tqdm-joblib
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
43
|
+
Requires-Dist: deptry; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
<div align="center">
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
# TOAD: **T**ipping and **O**ther **A**brupt events **D**etector
|
|
51
|
+
|
|
52
|
+
[](https://toad-docs.pages.dev)
|
|
53
|
+
[]()
|
|
54
|
+
[](https://github.com/tipmip-methods/toad/actions/workflows/build_and_tests.yml)
|
|
55
|
+
[](https://www.python.org/) [](LICENSE.txt) <br>
|
|
56
|
+
[](https://doi.org/10.5281/zenodo.18316437)
|
|
57
|
+
[](https://github.com/astral-sh/ruff)
|
|
58
|
+
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
TOAD is a **Python** package designed for **detecting and clustering spatio-temporal patterns in gridded Earth-system datasets**, such as model outputs. The input data should be structured as a 3D array in the format `space` × `space` × `time`, where `time` can represent actual time or some other forcing variable or bifurcation parameter. TOAD provides a streamlined pipeline for identifying and analyzing spatio-temporal regions or clusters that exhibit similar dynamical responses to external forcing.
|
|
62
|
+
|
|
63
|
+
Currently, TOAD focuses on identifying regions that experience similar abrupt transitions, such as the sudden loss of ice volume in a specific area. The goal, however, is to expand the package's functionality to support broader use cases, enabling the detection and clustering of diverse types of dynamical shifts across a wide range of systems.
|
|
64
|
+
|
|
65
|
+
The TOAD pipeline consists of three main components:
|
|
66
|
+
|
|
67
|
+
1. **Shift Detection:** Performs time series analysis at each individual grid cell to identify abrupt transitions or dynamical shifts using configurable detection methods (e.g., ASDETECT) with adjustable sensitivity parameters.
|
|
68
|
+
2. **Clustering:** Groups the detected shifts spatially and temporally (or along a bifurcation parameter) to reveal cohesive patterns using clustering methods (e.g., HDBSCAN) with configurable space/time scaling.
|
|
69
|
+
3. **Aggregation & Synthesis:** Aggregates results across multiple cluster maps from different datasets, models, variables, realisations, or methods to produce consensus clusters and statistics, and generates plots and summaries of the identified clusters for insights and interpretation.
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+

|
|
73
|
+
|
|
74
|
+
TOAD's core functionality is exposed through the `TOAD` class, which analyzes netCDF files or xarray datasets. The primary methods - `compute_shifts`, `compute_clusters`, and `aggregate.cluster_consensus()` - handle the three main pipeline steps. The pipeline supports aggregation of results across multiple runs, enabling consensus-based analysis. Additional helper functions and visualization tools make it easy to explore and understand the results.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
Until TOAD is published on pip/conda you can install it like this:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
$ git clone https://github.com/tipmip-methods/toad.git
|
|
83
|
+
$ cd toad
|
|
84
|
+
$ pip install .
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Simple use case
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from toad import TOAD
|
|
91
|
+
from toad.shifts import ASDETECT
|
|
92
|
+
from sklearn.cluster import HDBSCAN
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# init TOAD object with ice-thickness field and a custom time dimension.
|
|
96
|
+
td = TOAD("ice_thickness.nc", time_dim="GMST")
|
|
97
|
+
|
|
98
|
+
# Compute shifts for variable 'thk' using the method ASDETECT (Boulton & Lenton, 2019)
|
|
99
|
+
td.compute_shifts("thk", method=ASDETECT())
|
|
100
|
+
|
|
101
|
+
# Compute clusters using HDBSCAN from scikit-learn (McInnes, 2017)
|
|
102
|
+
td.compute_clusters(
|
|
103
|
+
var="thk",
|
|
104
|
+
method=HDBSCAN(min_cluster_size=10),
|
|
105
|
+
time_weight=1.5,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Plot largest clusters in ccrs.SouthPolarStereo() projection
|
|
109
|
+
td.plot.overview("thk", map_style={"projection": "south_pole"})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
<div align="center">
|
|
113
|
+
<img src="docs/source/resources/cluster_overview_example.png" width="1000px" alt="Cluster Overview Example">
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
For more details, check out the tutorials.
|
|
117
|
+
|
|
118
|
+
## Tutorials
|
|
119
|
+
|
|
120
|
+
- [Basics](https://github.com/tipmip-methods/toad/blob/main/tutorials/basics.ipynb): Learn the core concepts and workflow
|
|
121
|
+
- [Visualization](https://github.com/tipmip-methods/toad/blob/main/tutorials/visualisation_examples.ipynb): Explore the plotting capabilities
|
|
122
|
+
- [Custom Clustering](https://github.com/tipmip-methods/toad/blob/main/tutorials/clustering_methods.ipynb): Implement your own clustering methods
|
|
123
|
+
- [Custom Shift Detection](https://github.com/tipmip-methods/toad/blob/main/tutorials/shift_detection_methods.ipynb): Create new shift detection algorithms
|
|
124
|
+
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
$ git clone https://github.com/tipmip-methods/toad.git
|
|
129
|
+
$ cd toad
|
|
130
|
+
$ pip install -e .[dev]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The `-e` flag installs the package in "editable" mode, which means changes to the source code are immediately reflected without needing to reinstall.
|
|
134
|
+
|
|
135
|
+
For more information on contributing, code formatting, and our development workflow, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
136
|
+
|
|
137
|
+
## Citation
|
|
138
|
+
|
|
139
|
+
If you use TOAD in your research, please cite:
|
|
140
|
+
|
|
141
|
+
**TOAD package:**
|
|
142
|
+
Harteg, J., Roehrich, L., De Maeyer, K., Garbe, J., Sakschewski, B., Klose, A. K., Donges, J., Winkelmann, R., and Loriani, S.: TOAD: Tipping and Other Abrupt events Detector, Zenodo, https://doi.org/10.5281/zenodo.18316437, 2026.
|
|
143
|
+
|
|
144
|
+
*Note: This DOI always points to the latest release version.*
|
|
145
|
+
|
|
146
|
+
**TOAD methodology paper (submitted):**
|
|
147
|
+
Harteg, J., Roehrich, L., De Maeyer, K., Garbe, J., Sakschewski, B., Klose, A. K., Donges, J., Winkelmann, R., and Loriani, S.: TOAD v1.0: A Python Framework for Detecting Abrupt Shifts and Coherent Spatial Domains in Earth-System Data, Geosci. Model Dev., submitted, 2026.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
TOAD is licensed under the BSD 2-Clause License. See [LICENSE.txt](LICENSE.txt) for details.
|
|
152
|
+
|
|
153
|
+
## References
|
|
154
|
+
|
|
155
|
+
- Boulton, C. A., & Lenton, T. M. (2019). A new method for detecting abrupt shifts in time series. F1000Research, 8, 746. [https://doi.org/10.12688/F1000RESEARCH.19310.1](https://doi.org/10.12688/F1000RESEARCH.19310.1)
|
|
156
|
+
- McInnes, L., Healy, J., & Astels, S. (2017). hdbscan: Hierarchical density based clustering. J. Open Source Softw., 2(11), 205. [https://doi.org/10.21105/joss.00205](https://doi.org/10.21105/joss.00205)
|
|
157
|
+
- The scikit-learn developers. (2025). scikit-learn. Zenodo. [https://doi.org/10.5281/zenodo.591564](https://doi.org/10.5281/zenodo.591564)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
# TOAD: **T**ipping and **O**ther **A**brupt events **D**etector
|
|
6
|
+
|
|
7
|
+
[](https://toad-docs.pages.dev)
|
|
8
|
+
[]()
|
|
9
|
+
[](https://github.com/tipmip-methods/toad/actions/workflows/build_and_tests.yml)
|
|
10
|
+
[](https://www.python.org/) [](LICENSE.txt) <br>
|
|
11
|
+
[](https://doi.org/10.5281/zenodo.18316437)
|
|
12
|
+
[](https://github.com/astral-sh/ruff)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
TOAD is a **Python** package designed for **detecting and clustering spatio-temporal patterns in gridded Earth-system datasets**, such as model outputs. The input data should be structured as a 3D array in the format `space` × `space` × `time`, where `time` can represent actual time or some other forcing variable or bifurcation parameter. TOAD provides a streamlined pipeline for identifying and analyzing spatio-temporal regions or clusters that exhibit similar dynamical responses to external forcing.
|
|
17
|
+
|
|
18
|
+
Currently, TOAD focuses on identifying regions that experience similar abrupt transitions, such as the sudden loss of ice volume in a specific area. The goal, however, is to expand the package's functionality to support broader use cases, enabling the detection and clustering of diverse types of dynamical shifts across a wide range of systems.
|
|
19
|
+
|
|
20
|
+
The TOAD pipeline consists of three main components:
|
|
21
|
+
|
|
22
|
+
1. **Shift Detection:** Performs time series analysis at each individual grid cell to identify abrupt transitions or dynamical shifts using configurable detection methods (e.g., ASDETECT) with adjustable sensitivity parameters.
|
|
23
|
+
2. **Clustering:** Groups the detected shifts spatially and temporally (or along a bifurcation parameter) to reveal cohesive patterns using clustering methods (e.g., HDBSCAN) with configurable space/time scaling.
|
|
24
|
+
3. **Aggregation & Synthesis:** Aggregates results across multiple cluster maps from different datasets, models, variables, realisations, or methods to produce consensus clusters and statistics, and generates plots and summaries of the identified clusters for insights and interpretation.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
TOAD's core functionality is exposed through the `TOAD` class, which analyzes netCDF files or xarray datasets. The primary methods - `compute_shifts`, `compute_clusters`, and `aggregate.cluster_consensus()` - handle the three main pipeline steps. The pipeline supports aggregation of results across multiple runs, enabling consensus-based analysis. Additional helper functions and visualization tools make it easy to explore and understand the results.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Until TOAD is published on pip/conda you can install it like this:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
$ git clone https://github.com/tipmip-methods/toad.git
|
|
38
|
+
$ cd toad
|
|
39
|
+
$ pip install .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Simple use case
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from toad import TOAD
|
|
46
|
+
from toad.shifts import ASDETECT
|
|
47
|
+
from sklearn.cluster import HDBSCAN
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# init TOAD object with ice-thickness field and a custom time dimension.
|
|
51
|
+
td = TOAD("ice_thickness.nc", time_dim="GMST")
|
|
52
|
+
|
|
53
|
+
# Compute shifts for variable 'thk' using the method ASDETECT (Boulton & Lenton, 2019)
|
|
54
|
+
td.compute_shifts("thk", method=ASDETECT())
|
|
55
|
+
|
|
56
|
+
# Compute clusters using HDBSCAN from scikit-learn (McInnes, 2017)
|
|
57
|
+
td.compute_clusters(
|
|
58
|
+
var="thk",
|
|
59
|
+
method=HDBSCAN(min_cluster_size=10),
|
|
60
|
+
time_weight=1.5,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Plot largest clusters in ccrs.SouthPolarStereo() projection
|
|
64
|
+
td.plot.overview("thk", map_style={"projection": "south_pole"})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
<div align="center">
|
|
68
|
+
<img src="docs/source/resources/cluster_overview_example.png" width="1000px" alt="Cluster Overview Example">
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
For more details, check out the tutorials.
|
|
72
|
+
|
|
73
|
+
## Tutorials
|
|
74
|
+
|
|
75
|
+
- [Basics](https://github.com/tipmip-methods/toad/blob/main/tutorials/basics.ipynb): Learn the core concepts and workflow
|
|
76
|
+
- [Visualization](https://github.com/tipmip-methods/toad/blob/main/tutorials/visualisation_examples.ipynb): Explore the plotting capabilities
|
|
77
|
+
- [Custom Clustering](https://github.com/tipmip-methods/toad/blob/main/tutorials/clustering_methods.ipynb): Implement your own clustering methods
|
|
78
|
+
- [Custom Shift Detection](https://github.com/tipmip-methods/toad/blob/main/tutorials/shift_detection_methods.ipynb): Create new shift detection algorithms
|
|
79
|
+
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
$ git clone https://github.com/tipmip-methods/toad.git
|
|
84
|
+
$ cd toad
|
|
85
|
+
$ pip install -e .[dev]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `-e` flag installs the package in "editable" mode, which means changes to the source code are immediately reflected without needing to reinstall.
|
|
89
|
+
|
|
90
|
+
For more information on contributing, code formatting, and our development workflow, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
91
|
+
|
|
92
|
+
## Citation
|
|
93
|
+
|
|
94
|
+
If you use TOAD in your research, please cite:
|
|
95
|
+
|
|
96
|
+
**TOAD package:**
|
|
97
|
+
Harteg, J., Roehrich, L., De Maeyer, K., Garbe, J., Sakschewski, B., Klose, A. K., Donges, J., Winkelmann, R., and Loriani, S.: TOAD: Tipping and Other Abrupt events Detector, Zenodo, https://doi.org/10.5281/zenodo.18316437, 2026.
|
|
98
|
+
|
|
99
|
+
*Note: This DOI always points to the latest release version.*
|
|
100
|
+
|
|
101
|
+
**TOAD methodology paper (submitted):**
|
|
102
|
+
Harteg, J., Roehrich, L., De Maeyer, K., Garbe, J., Sakschewski, B., Klose, A. K., Donges, J., Winkelmann, R., and Loriani, S.: TOAD v1.0: A Python Framework for Detecting Abrupt Shifts and Coherent Spatial Domains in Earth-System Data, Geosci. Model Dev., submitted, 2026.
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
TOAD is licensed under the BSD 2-Clause License. See [LICENSE.txt](LICENSE.txt) for details.
|
|
107
|
+
|
|
108
|
+
## References
|
|
109
|
+
|
|
110
|
+
- Boulton, C. A., & Lenton, T. M. (2019). A new method for detecting abrupt shifts in time series. F1000Research, 8, 746. [https://doi.org/10.12688/F1000RESEARCH.19310.1](https://doi.org/10.12688/F1000RESEARCH.19310.1)
|
|
111
|
+
- McInnes, L., Healy, J., & Astels, S. (2017). hdbscan: Hierarchical density based clustering. J. Open Source Softw., 2(11), 205. [https://doi.org/10.21105/joss.00205](https://doi.org/10.21105/joss.00205)
|
|
112
|
+
- The scikit-learn developers. (2025). scikit-learn. Zenodo. [https://doi.org/10.5281/zenodo.591564](https://doi.org/10.5281/zenodo.591564)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import inspect # needed in linkcode py-function to connect documentation to source link
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
module_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
|
|
6
|
+
sys.path.insert(0, module_path)
|
|
7
|
+
|
|
8
|
+
# Configuration file for the Sphinx documentation builder.
|
|
9
|
+
#
|
|
10
|
+
# For the full list of built-in configuration values, see the documentation:
|
|
11
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
12
|
+
|
|
13
|
+
# -- Project information -----------------------------------------------------
|
|
14
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
15
|
+
|
|
16
|
+
project = "toad"
|
|
17
|
+
copyright = "2026, TOAD Developers"
|
|
18
|
+
author = "TOAD Developers"
|
|
19
|
+
language = "en"
|
|
20
|
+
|
|
21
|
+
# -- General configuration ---------------------------------------------------
|
|
22
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
23
|
+
|
|
24
|
+
extensions = [
|
|
25
|
+
"sphinx.ext.doctest",
|
|
26
|
+
"sphinx.ext.autodoc",
|
|
27
|
+
"sphinx.ext.doctest",
|
|
28
|
+
"sphinx.ext.autosummary",
|
|
29
|
+
# "sphinx.ext.linkcode",
|
|
30
|
+
"sphinx.ext.napoleon", # Support for NumPy and Google style docstrings
|
|
31
|
+
"sphinx.ext.autodoc.typehints", # to pull types from function definitions
|
|
32
|
+
#'sphinx.ext.viewcode',
|
|
33
|
+
"myst_nb", # allows to include Jupyter Notebooks and Markdowns
|
|
34
|
+
]
|
|
35
|
+
autodoc_default_options = {
|
|
36
|
+
"members": True,
|
|
37
|
+
"undoc-members": True,
|
|
38
|
+
"private-members": False,
|
|
39
|
+
"show-inheritance": True,
|
|
40
|
+
"special-members": False, # Exclude special methods like __init__, __repr__, etc.
|
|
41
|
+
"exclude-members": "__weakref__,__dict__,__module__,__doc__,__slots__", # Exclude problematic attributes
|
|
42
|
+
"show-signature": True,
|
|
43
|
+
"show-signature-with-docstring": False, # Don't show docstring in signature for dataclasses
|
|
44
|
+
}
|
|
45
|
+
autosummary_generate = True
|
|
46
|
+
myst_fence_as_directive = ["mermaid"]
|
|
47
|
+
myst_heading_anchors = 2 # depth of implicit target for cross references -> needed for git_version_control.rst
|
|
48
|
+
|
|
49
|
+
nb_execution_mode = "off" # Prevent myst_nb from executing notebooks
|
|
50
|
+
|
|
51
|
+
# Autodoc type hints settings
|
|
52
|
+
autodoc_typehints = "description"
|
|
53
|
+
autodoc_typehints_format = "short"
|
|
54
|
+
|
|
55
|
+
# Napoleon settings
|
|
56
|
+
napoleon_google_docstring = True
|
|
57
|
+
napoleon_numpy_docstring = True
|
|
58
|
+
napoleon_include_init_with_doc = False
|
|
59
|
+
napoleon_include_private_with_doc = False
|
|
60
|
+
napoleon_include_special_with_doc = True
|
|
61
|
+
napoleon_use_admonition_for_examples = False
|
|
62
|
+
napoleon_use_admonition_for_notes = False
|
|
63
|
+
napoleon_use_admonition_for_references = False
|
|
64
|
+
napoleon_use_ivar = False
|
|
65
|
+
napoleon_use_param = True
|
|
66
|
+
napoleon_use_keyword = True
|
|
67
|
+
napoleon_use_rtype = True
|
|
68
|
+
napoleon_preprocess_types = True
|
|
69
|
+
napoleon_type_aliases = None
|
|
70
|
+
napoleon_attr_annotations = True
|
|
71
|
+
napoleon_include_ivar_with_doc = False # Don't show instance variables for dataclasses
|
|
72
|
+
|
|
73
|
+
templates_path = ["_templates"]
|
|
74
|
+
exclude_patterns = []
|
|
75
|
+
master_doc = "sidebar_main_nav_links"
|
|
76
|
+
modindex_common_prefix = ["toad."] # ignored prefixes for module index sorting
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
remove_from_toctrees = [
|
|
80
|
+
"generated/*"
|
|
81
|
+
] # remove generated files from the table of contents, this folder is created by the sphinx-apidoc command
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# -- Options for HTML output -------------------------------------------------
|
|
85
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
86
|
+
|
|
87
|
+
html_theme = "sphinxawesome_theme"
|
|
88
|
+
|
|
89
|
+
# Other themes to try in the future maybe:
|
|
90
|
+
# html_theme = 'furo'
|
|
91
|
+
# html_theme = 'sphinx_book_theme'
|
|
92
|
+
|
|
93
|
+
html_static_path = ["_static", "resources"]
|
|
94
|
+
html_css_files = [
|
|
95
|
+
"custom.css",
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
# -> Theme Specific HTML ouptut options
|
|
99
|
+
html_sidebars = {"**": ["sidebar_main_nav_links.html", "sidebar_toc.html"]}
|
|
100
|
+
html_logo = "resources/toad.png"
|
|
101
|
+
html_permalinks_icon = "<span>¶</span>" # change the default anchor icon, paragraph mark only appears when hovering over the heading
|
|
102
|
+
|
|
103
|
+
# -- Function for sphinx extention linkcode -------------------------------
|
|
104
|
+
|
|
105
|
+
# Look at xarray documentation for a more elaborate example.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def linkcode_resolve(domain, info):
|
|
109
|
+
"""
|
|
110
|
+
Determine the URL corresponding to Python object.
|
|
111
|
+
The implementation is based on xarray doc/source/conf.py.
|
|
112
|
+
"""
|
|
113
|
+
if domain != "py":
|
|
114
|
+
print(f"\nWARNING: Domain is not 'py'. Object: {domain}")
|
|
115
|
+
return None
|
|
116
|
+
if not info["module"]:
|
|
117
|
+
print(f"\nWARNING: Module is not specified. Object: {info}")
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
modname = info["module"]
|
|
121
|
+
fullname = info["fullname"]
|
|
122
|
+
|
|
123
|
+
submod = sys.modules.get(modname)
|
|
124
|
+
if submod is None:
|
|
125
|
+
print(f"\nWARNING: Could not find module. Object: {submod}")
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
obj = submod
|
|
129
|
+
for part in fullname.split("."):
|
|
130
|
+
try:
|
|
131
|
+
obj = getattr(obj, part)
|
|
132
|
+
except AttributeError:
|
|
133
|
+
print(f"\nWARNING: Could not find attribute. Object: {obj}")
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
# **Skip properties to avoid the error**
|
|
137
|
+
if isinstance(obj, property):
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
# **Skip dataclass instances to avoid the error**
|
|
141
|
+
if hasattr(obj, "__class__") and hasattr(obj.__class__, "__dataclass_fields__"):
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
# **Skip Numba JIT-compiled functions to avoid CPUDispatcher error**
|
|
145
|
+
if hasattr(obj, "__class__") and "CPUDispatcher" in str(type(obj)):
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
# Get the source file and line numbers
|
|
150
|
+
sourcefile = inspect.getsourcefile(obj)
|
|
151
|
+
if sourcefile is None:
|
|
152
|
+
print(f"\nWARNING: No source file found. Object: {sourcefile}")
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
source, lineno = inspect.getsourcelines(obj)
|
|
156
|
+
except OSError:
|
|
157
|
+
lineno = None
|
|
158
|
+
|
|
159
|
+
# identify start and end line number of code in source file
|
|
160
|
+
linespec = f"#L{lineno}-L{lineno + len(source) - 1}" if lineno else ""
|
|
161
|
+
|
|
162
|
+
# Check if toad module file exists and is not None
|
|
163
|
+
toad_module = sys.modules.get("toad")
|
|
164
|
+
if toad_module is None or toad_module.__file__ is None:
|
|
165
|
+
print("\nWARNING: Could not find toad module or its __file__ attribute")
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
# Ensure sourcefile is not None before using it
|
|
169
|
+
if sourcefile is None:
|
|
170
|
+
print("\nWARNING: No source file found for object")
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
# Adjust for objects imported into __init__.py
|
|
174
|
+
# Use the actual source file instead of relying on the module name
|
|
175
|
+
relpath = os.path.relpath(sourcefile, start=os.path.dirname(toad_module.__file__))
|
|
176
|
+
|
|
177
|
+
# Build the GitHub URL
|
|
178
|
+
return f"https://github.com/tipmip-methods/toad/tree/main/toad/{relpath}{linespec}"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# toml-file started Feb 2025 by Lukas Röhrich
|
|
2
|
+
#
|
|
3
|
+
# This file acts as a configuration file for the toad package
|
|
4
|
+
# by Potsdam Institute for Climate Impact Research, GER
|
|
5
|
+
#
|
|
6
|
+
# Tutorial on how to setup this config file:
|
|
7
|
+
# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
|
|
8
|
+
|
|
9
|
+
# choose build-backend
|
|
10
|
+
[build-system]
|
|
11
|
+
build-backend = "setuptools.build_meta"
|
|
12
|
+
requires = [
|
|
13
|
+
"setuptools",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
# basic metadata
|
|
17
|
+
[project]
|
|
18
|
+
name = "tipmip-toad"
|
|
19
|
+
dynamic = ["version"]
|
|
20
|
+
description = "Tipping and Other Abrupt events Detector"
|
|
21
|
+
readme = "README.md"
|
|
22
|
+
keywords = ["tipping", "tipping points", "climate", "abrupt shifts", "earth system"]
|
|
23
|
+
license = "BSD-2-Clause"
|
|
24
|
+
requires-python = ">=3.10"
|
|
25
|
+
authors = [
|
|
26
|
+
{name = "Jakob Harteg", email = "jakob.harteg@pik-potsdam.de"},
|
|
27
|
+
{name = "Lukas Roehrich", email = "lukas.roehrich@pik-potsdam.de"},
|
|
28
|
+
{name = "Sina Loriani", email = "sina.loriani@pik-potsdam.de"}
|
|
29
|
+
]
|
|
30
|
+
maintainers = [
|
|
31
|
+
{name = "Jakob Harteg", email = "jakob.harteg@pik-potsdam.de"}
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
"Development Status :: 5 - Production/Stable",
|
|
35
|
+
"Topic :: Scientific/Engineering",
|
|
36
|
+
"Topic :: Scientific/Engineering :: Atmospheric Science",
|
|
37
|
+
"Topic :: Scientific/Engineering :: Oceanography",
|
|
38
|
+
"Intended Audience :: Science/Research",
|
|
39
|
+
"Programming Language :: Python :: 3",
|
|
40
|
+
"Programming Language :: Python :: 3.10",
|
|
41
|
+
"Programming Language :: Python :: 3.11",
|
|
42
|
+
"Programming Language :: Python :: 3.12",
|
|
43
|
+
"Operating System :: OS Independent",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
dependencies = [
|
|
47
|
+
"numpy>=2.2.0,<2.3.0", # Pin to NumPy 2.2.x to ensure consistent BLAS/LAPACK implementation across platforms
|
|
48
|
+
"matplotlib",
|
|
49
|
+
"scipy>=1.15.0,<1.17.0", # Python 3.10 gets 1.15.x, Python 3.11+ gets 1.16.x
|
|
50
|
+
"scikit-learn>=1.7.1,<1.8.0", # Pin to scikit-learn 1.7.x for consistent HDBSCAN clustering results
|
|
51
|
+
"xarray",
|
|
52
|
+
"netcdf4", # pipreqs didn't find this, but needed for xarray as optional dep to read *.nc files
|
|
53
|
+
"cartopy",
|
|
54
|
+
"pandas",
|
|
55
|
+
"numba",
|
|
56
|
+
"healpix",
|
|
57
|
+
"optuna",
|
|
58
|
+
"cftime",
|
|
59
|
+
"joblib",
|
|
60
|
+
"tqdm-joblib"
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[project.optional-dependencies]
|
|
64
|
+
dev = [
|
|
65
|
+
"pre-commit",
|
|
66
|
+
"ruff",
|
|
67
|
+
"pytest",
|
|
68
|
+
"pytest-cov",
|
|
69
|
+
"deptry",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[project.urls]
|
|
73
|
+
Homepage = "https://tipmip.pik-potsdam.de/"
|
|
74
|
+
Repository = "https://github.com/tipmip-methods/toad"
|
|
75
|
+
|
|
76
|
+
[tool.setuptools]
|
|
77
|
+
packages = {find = {}}
|
|
78
|
+
|
|
79
|
+
[tool.setuptools.package-data]
|
|
80
|
+
toad = ["py.typed"]
|
|
81
|
+
|
|
82
|
+
[tool.setuptools.dynamic]
|
|
83
|
+
version = {attr = "toad._version.__version__"}
|
|
84
|
+
|
|
85
|
+
[tool.deptry.per_rule_ignores]
|
|
86
|
+
DEP002 = ["netcdf4", "pre-commit", "ruff", "pytest", "pytest-cov", "deptry"]
|
|
87
|
+
|
|
88
|
+
[tool.deptry]
|
|
89
|
+
ignore_notebooks = true
|
|
90
|
+
|
|
91
|
+
# suppress warning about assuming corresponding module name
|
|
92
|
+
[tool.deptry.package_module_name_map]
|
|
93
|
+
numpy = "numpy"
|
|
94
|
+
matplotlib = "matplotlib"
|
|
95
|
+
scipy = "scipy"
|
|
96
|
+
xarray = "xarray"
|
|
97
|
+
netcdf4 = "netcdf4"
|
|
98
|
+
cartopy = "cartopy"
|
|
99
|
+
pandas = "pandas"
|
|
100
|
+
scikit-learn = "sklearn"
|
|
101
|
+
numba = "numba"
|
|
102
|
+
healpix = "healpix"
|
|
103
|
+
optuna = "optuna"
|
|
104
|
+
cftime = "cftime"
|
|
105
|
+
joblib = "joblib"
|
|
106
|
+
tqdm-joblib = "tqdm_joblib"
|
|
107
|
+
|
|
108
|
+
[tool.mypy]
|
|
109
|
+
python_version = "3.12"
|
|
110
|
+
warn_return_any = true
|
|
111
|
+
warn_unused_configs = true
|
|
112
|
+
disallow_untyped_defs = false
|
|
113
|
+
exclude = [
|
|
114
|
+
"build/",
|
|
115
|
+
"build/lib/",
|
|
116
|
+
"toad.egg-info/",
|
|
117
|
+
"docs/",
|
|
118
|
+
"tutorials/",
|
|
119
|
+
"test_artifacts/",
|
|
120
|
+
".*",
|
|
121
|
+
]
|