rainfallqc 0.0.9__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 (28) hide show
  1. rainfallqc-0.0.9/LICENSE +33 -0
  2. rainfallqc-0.0.9/PKG-INFO +201 -0
  3. rainfallqc-0.0.9/README.rst +146 -0
  4. rainfallqc-0.0.9/pyproject.toml +158 -0
  5. rainfallqc-0.0.9/src/rainfallqc/__init__.py +22 -0
  6. rainfallqc-0.0.9/src/rainfallqc/checks/__init__.py +1 -0
  7. rainfallqc-0.0.9/src/rainfallqc/checks/comparison_checks.py +342 -0
  8. rainfallqc-0.0.9/src/rainfallqc/checks/gauge_checks.py +234 -0
  9. rainfallqc-0.0.9/src/rainfallqc/checks/neighbourhood_checks.py +341 -0
  10. rainfallqc-0.0.9/src/rainfallqc/checks/timeseries_checks.py +1042 -0
  11. rainfallqc-0.0.9/src/rainfallqc/core/__init__.py +1 -0
  12. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_CDD_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  13. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_CWD_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  14. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_PRCPTOT_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  15. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_R99p_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  16. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_Rx1day_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  17. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/RawData_HADEX2_SDII_1951-2010_ANN_from-90to90_from-180to180.nc +0 -0
  18. rainfallqc-0.0.9/src/rainfallqc/data/ETCCDI/__init__.py +1 -0
  19. rainfallqc-0.0.9/src/rainfallqc/data/__init__.py +1 -0
  20. rainfallqc-0.0.9/src/rainfallqc/qc_frameworks/__init__.py +1 -0
  21. rainfallqc-0.0.9/src/rainfallqc/qc_frameworks/apply_qc_framework.py +63 -0
  22. rainfallqc-0.0.9/src/rainfallqc/qc_frameworks/inbuilt_qc_frameworks.py +25 -0
  23. rainfallqc-0.0.9/src/rainfallqc/utils/__init__.py +1 -0
  24. rainfallqc-0.0.9/src/rainfallqc/utils/data_readers.py +713 -0
  25. rainfallqc-0.0.9/src/rainfallqc/utils/data_utils.py +259 -0
  26. rainfallqc-0.0.9/src/rainfallqc/utils/neighbourhood_utils.py +355 -0
  27. rainfallqc-0.0.9/src/rainfallqc/utils/spatial_utils.py +40 -0
  28. rainfallqc-0.0.9/src/rainfallqc/utils/stats.py +260 -0
@@ -0,0 +1,33 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Quality control procedure for rainfall data
5
+ Copyright (C) 2025 Tom Keel
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ Also add information on how to contact you by electronic and paper mail.
21
+
22
+ You should also get your employer (if you work as a programmer) or school,
23
+ if any, to sign a "copyright disclaimer" for the program, if necessary.
24
+ For more information on this, and how to apply and follow the GNU GPL, see
25
+ <http://www.gnu.org/licenses/>.
26
+
27
+ The GNU General Public License does not permit incorporating your program
28
+ into proprietary programs. If your program is a subroutine library, you
29
+ may consider it more useful to permit linking proprietary applications with
30
+ the library. If this is what you want to do, use the GNU Lesser General
31
+ Public License instead of this License. But first, please read
32
+ <http://www.gnu.org/philosophy/why-not-lgpl.html>.
33
+
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: rainfallqc
3
+ Version: 0.0.9
4
+ Summary: Quality control for rainfall data
5
+ Author-email: Tom Keel <tomkee@ceh.ac.uk>
6
+ Maintainer-email: Tom Keel <tomkee@ceh.ac.uk>
7
+ Requires-Python: >=3.10.0
8
+ Description-Content-Type: text/x-rst
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
+ Classifier: Natural Language :: English
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Hydrology
21
+ License-File: LICENSE
22
+ Requires-Dist: scipy
23
+ Requires-Dist: numpy
24
+ Requires-Dist: polars
25
+ Requires-Dist: pandas
26
+ Requires-Dist: xarray
27
+ Requires-Dist: bottleneck
28
+ Requires-Dist: geopy
29
+ Requires-Dist: pip ; extra == "dev"
30
+ Requires-Dist: numpy ; extra == "dev"
31
+ Requires-Dist: bump-my-version ; extra == "dev"
32
+ Requires-Dist: ruff ; extra == "dev"
33
+ Requires-Dist: black ; extra == "dev"
34
+ Requires-Dist: pre_commit ; extra == "dev"
35
+ Requires-Dist: pylint ; extra == "dev"
36
+ Requires-Dist: pytest ; extra == "dev"
37
+ Requires-Dist: pytest-cov ; extra == "dev"
38
+ Requires-Dist: matplotlib ; extra == "dev"
39
+ Requires-Dist: sphinx ; extra == "dev"
40
+ Requires-Dist: sphinx ; extra == "docs"
41
+ Requires-Dist: sphinx-copybutton ; extra == "docs"
42
+ Requires-Dist: sphinx-rtd-theme ; extra == "docs"
43
+ Requires-Dist: mypy ; extra == "lint"
44
+ Requires-Dist: ruff ; extra == "lint"
45
+ Requires-Dist: pytest ; extra == "test"
46
+ Requires-Dist: pytest-cov ; extra == "test"
47
+ Project-URL: bugs, https://github.com/thomasjkeel/RainfallQC/issues
48
+ Project-URL: changelog, https://github.com/thomasjkeel/RainfallQC/blob/master/changelog.md
49
+ Project-URL: homepage, https://github.com/thomasjkeel/RainfallQC
50
+ Provides-Extra: dev
51
+ Provides-Extra: docs
52
+ Provides-Extra: lint
53
+ Provides-Extra: test
54
+
55
+ ===============================================
56
+ RainfallQC - Quality control for rainfall data
57
+ ===============================================
58
+
59
+ ..
60
+ image:: https://img.shields.io/pypi/v/rainfallqc.svg
61
+ :target: https://pypi.python.org/pypi/rainfallqc
62
+
63
+ ..
64
+ image:: https://readthedocs.org/projects/rainfallqc/badge/?version=latest
65
+ :target: https://rainfallqc.readthedocs.io/en/latest/?version=latest
66
+ :alt: Documentation Status
67
+
68
+
69
+ Provides methods for running QC frameworks.
70
+
71
+ **NOTEBOOK DEMO AVAILABLE** `HERE <https://github.com/Thomasjkeel/RainfallQC-notebooks/blob/main/notebooks/demo/rainfallQC_demo.ipynb>`_
72
+
73
+ Please email tomkee@ceh.ac.uk if you have any questions.
74
+
75
+ Project To Do:
76
+
77
+ - add flag descriptions
78
+ - Use timestep str maker to the checks
79
+
80
+ Example use
81
+ -----------
82
+
83
+ Example 1. - Individual quality checks on single rain gauge
84
+ ===========================================================
85
+
86
+ .. code-block:: python
87
+
88
+ # Load two types of QC'ing modules from RainfallQC
89
+ from rainfallqc import gauge_checks, comparison_checks
90
+
91
+ # 1. Simple 1 gauge QC
92
+ # 1.1. Run 1 qc method for 1 gauge
93
+ intermittency_flag = gauge_checks.check_intermittency(data, rain_col="rain_mm")
94
+
95
+ # 1.2. Run 1 qc method for 1 gauge using in-built comparison dataset
96
+ wr_flags = comparison_checks.check_exceedance_of_rainfall_world_record(data, rain_col="rain_mm", time_res='hourly')
97
+
98
+ # 1.3. Run 1 qc method for 1 gauge using in-built comparison dataset and location of gauge
99
+ rx1day_flags = comparison_checks.check_annual_exceedance_etccdi_rx1day(data, rain_col="rain_mm", gauge_lon=1.0, gauge_lat=55.0)
100
+
101
+
102
+ Example 2. - Individual quality checks on networks of rain gauges
103
+ =================================================================
104
+
105
+ .. code-block:: python
106
+
107
+ # 2. Run neighbour/network checks on a subset of a rain gauge network
108
+ from rainfallqc import neighbourhood_checks
109
+ from rainfallqc.utils import data_readers
110
+
111
+ # 2.1. Read in GDSR gauge network metadata
112
+ gdsr_obj = data_readers.GDSRNetworkReader(path_to_gdsr_dir="./tests/data/GDSR/")
113
+
114
+ # 2.2. subset by max 10 gauges within 50 km and with at least 500 days of overlap
115
+ nearby_ids = list(
116
+ gdsr_obj.get_nearest_overlapping_neighbours_to_target(
117
+ target_id="DE_00310", distance_threshold=50, n_closest=10, min_overlap_days=500
118
+ )
119
+ )
120
+ nearby_ids.append(target_id)
121
+ nearby_data_paths = gdsr_obj.metadata.filter(pl.col("station_id").is_in(nearby_ids))["path"]
122
+
123
+ # 2.3. Load those nearest gauges from network metadata
124
+ gdsr_network = gdsr_obj.load_network_data(data_paths=nearby_data_paths)
125
+
126
+ # 2.4 Run a neighbourhood check (checking if suspiciously large rainfall values were seen in neighbours)
127
+ extreme_wet_flags = neighbourhood_checks.check_wet_neighbours(
128
+ gdsr_network,
129
+ target_gauge_col="rain_mm_DE_02483",
130
+ neighbouring_gauge_cols=gdsr_network.columns[1:], # exclude time
131
+ time_res="hourly",
132
+ wet_threshold=1.0, # threshold for rainfall intensity to be considered
133
+ min_n_neighbours=5, # number of neighbours needed for comparison
134
+ n_neighbours_ignored=0, # ignore no neighbours and include all
135
+ )
136
+
137
+ Example 3. - Applying a framework of QC methods (e.g. IntenseQC)
138
+ ================================================================
139
+
140
+ .. code-block:: python
141
+
142
+ # 3. Applying multiple QC methods in framework (e.g. IntenseQC)
143
+ from rainfallqc.qc_frameworks import apply_qc_framework
144
+
145
+ # 3.1. Decide which QC methods of IntenseQC will be run
146
+ qc_framework = "IntenseQC"
147
+ qc_methods_to_run = ["QC1", "QC8", "QC9", "QC10", "QC11", "QC12", "QC14", "QC15", "QC16"]
148
+
149
+ # 3.2 Decide which parameters for QC
150
+ qc_kwargs = {
151
+ "QC1": {"quantile": 5},
152
+ "QC14": {"wet_day_threshold": 1.0, "accumulation_multiplying_factor": 2.0},
153
+ "QC16": {
154
+ "neighbouring_gauge_cols": daily_gpcc_network.columns[2:],
155
+ "wet_threshold": 1.0,
156
+ "min_n_neighbours": 5,
157
+ "n_neighbours_ignored": 0,
158
+ },
159
+ # Shared defaults applied to all
160
+ "shared": {
161
+ "rain_col": "rain_mm_DE_02483",
162
+ "target_gauge_col": "rain_mm_DE_02483",
163
+ "gauge_lat": gpcc_metadata["latitude"],
164
+ "gauge_lon": gpcc_metadata["longitude"],
165
+ "time_res": "daily",
166
+ "data_resolution": 0.1,
167
+ },
168
+ }
169
+
170
+ # 3.3. Run QC methods on network data
171
+ qc_result = apply_qc_framework.run_qc_framework(
172
+ daily_gpcc_network, qc_framework=qc_framework, qc_methods_to_run=qc_methods_to_run, qc_kwargs=qc_kwargs
173
+ )
174
+
175
+
176
+ Other examples
177
+ ===================
178
+ Also see example Jupyter Notebooks here: https://github.com/Thomasjkeel/RainfallQC-notebooks/tree/main
179
+
180
+ Documents
181
+ ---------
182
+ * Free software: GNU General Public License v3
183
+ * Documentation: https://rainfallqc.readthedocs.io.
184
+
185
+
186
+ Features
187
+ --------
188
+
189
+ - 25 rainfall QC methods (all from IntenseQC)
190
+ - editable parameters so you can tweak thresholds, streak or accumulation lengths, and distances to neighbouring gauges
191
+
192
+ Credits
193
+ -------
194
+ Based on the IntenseQC: https://github.com/nclwater/intense-qc/tree/master
195
+
196
+
197
+ This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
198
+
199
+ .. _Cookiecutter: https://github.com/audreyr/cookiecutter
200
+ .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
201
+
@@ -0,0 +1,146 @@
1
+ ===============================================
2
+ RainfallQC - Quality control for rainfall data
3
+ ===============================================
4
+
5
+ ..
6
+ image:: https://img.shields.io/pypi/v/rainfallqc.svg
7
+ :target: https://pypi.python.org/pypi/rainfallqc
8
+
9
+ ..
10
+ image:: https://readthedocs.org/projects/rainfallqc/badge/?version=latest
11
+ :target: https://rainfallqc.readthedocs.io/en/latest/?version=latest
12
+ :alt: Documentation Status
13
+
14
+
15
+ Provides methods for running QC frameworks.
16
+
17
+ **NOTEBOOK DEMO AVAILABLE** `HERE <https://github.com/Thomasjkeel/RainfallQC-notebooks/blob/main/notebooks/demo/rainfallQC_demo.ipynb>`_
18
+
19
+ Please email tomkee@ceh.ac.uk if you have any questions.
20
+
21
+ Project To Do:
22
+
23
+ - add flag descriptions
24
+ - Use timestep str maker to the checks
25
+
26
+ Example use
27
+ -----------
28
+
29
+ Example 1. - Individual quality checks on single rain gauge
30
+ ===========================================================
31
+
32
+ .. code-block:: python
33
+
34
+ # Load two types of QC'ing modules from RainfallQC
35
+ from rainfallqc import gauge_checks, comparison_checks
36
+
37
+ # 1. Simple 1 gauge QC
38
+ # 1.1. Run 1 qc method for 1 gauge
39
+ intermittency_flag = gauge_checks.check_intermittency(data, rain_col="rain_mm")
40
+
41
+ # 1.2. Run 1 qc method for 1 gauge using in-built comparison dataset
42
+ wr_flags = comparison_checks.check_exceedance_of_rainfall_world_record(data, rain_col="rain_mm", time_res='hourly')
43
+
44
+ # 1.3. Run 1 qc method for 1 gauge using in-built comparison dataset and location of gauge
45
+ rx1day_flags = comparison_checks.check_annual_exceedance_etccdi_rx1day(data, rain_col="rain_mm", gauge_lon=1.0, gauge_lat=55.0)
46
+
47
+
48
+ Example 2. - Individual quality checks on networks of rain gauges
49
+ =================================================================
50
+
51
+ .. code-block:: python
52
+
53
+ # 2. Run neighbour/network checks on a subset of a rain gauge network
54
+ from rainfallqc import neighbourhood_checks
55
+ from rainfallqc.utils import data_readers
56
+
57
+ # 2.1. Read in GDSR gauge network metadata
58
+ gdsr_obj = data_readers.GDSRNetworkReader(path_to_gdsr_dir="./tests/data/GDSR/")
59
+
60
+ # 2.2. subset by max 10 gauges within 50 km and with at least 500 days of overlap
61
+ nearby_ids = list(
62
+ gdsr_obj.get_nearest_overlapping_neighbours_to_target(
63
+ target_id="DE_00310", distance_threshold=50, n_closest=10, min_overlap_days=500
64
+ )
65
+ )
66
+ nearby_ids.append(target_id)
67
+ nearby_data_paths = gdsr_obj.metadata.filter(pl.col("station_id").is_in(nearby_ids))["path"]
68
+
69
+ # 2.3. Load those nearest gauges from network metadata
70
+ gdsr_network = gdsr_obj.load_network_data(data_paths=nearby_data_paths)
71
+
72
+ # 2.4 Run a neighbourhood check (checking if suspiciously large rainfall values were seen in neighbours)
73
+ extreme_wet_flags = neighbourhood_checks.check_wet_neighbours(
74
+ gdsr_network,
75
+ target_gauge_col="rain_mm_DE_02483",
76
+ neighbouring_gauge_cols=gdsr_network.columns[1:], # exclude time
77
+ time_res="hourly",
78
+ wet_threshold=1.0, # threshold for rainfall intensity to be considered
79
+ min_n_neighbours=5, # number of neighbours needed for comparison
80
+ n_neighbours_ignored=0, # ignore no neighbours and include all
81
+ )
82
+
83
+ Example 3. - Applying a framework of QC methods (e.g. IntenseQC)
84
+ ================================================================
85
+
86
+ .. code-block:: python
87
+
88
+ # 3. Applying multiple QC methods in framework (e.g. IntenseQC)
89
+ from rainfallqc.qc_frameworks import apply_qc_framework
90
+
91
+ # 3.1. Decide which QC methods of IntenseQC will be run
92
+ qc_framework = "IntenseQC"
93
+ qc_methods_to_run = ["QC1", "QC8", "QC9", "QC10", "QC11", "QC12", "QC14", "QC15", "QC16"]
94
+
95
+ # 3.2 Decide which parameters for QC
96
+ qc_kwargs = {
97
+ "QC1": {"quantile": 5},
98
+ "QC14": {"wet_day_threshold": 1.0, "accumulation_multiplying_factor": 2.0},
99
+ "QC16": {
100
+ "neighbouring_gauge_cols": daily_gpcc_network.columns[2:],
101
+ "wet_threshold": 1.0,
102
+ "min_n_neighbours": 5,
103
+ "n_neighbours_ignored": 0,
104
+ },
105
+ # Shared defaults applied to all
106
+ "shared": {
107
+ "rain_col": "rain_mm_DE_02483",
108
+ "target_gauge_col": "rain_mm_DE_02483",
109
+ "gauge_lat": gpcc_metadata["latitude"],
110
+ "gauge_lon": gpcc_metadata["longitude"],
111
+ "time_res": "daily",
112
+ "data_resolution": 0.1,
113
+ },
114
+ }
115
+
116
+ # 3.3. Run QC methods on network data
117
+ qc_result = apply_qc_framework.run_qc_framework(
118
+ daily_gpcc_network, qc_framework=qc_framework, qc_methods_to_run=qc_methods_to_run, qc_kwargs=qc_kwargs
119
+ )
120
+
121
+
122
+ Other examples
123
+ ===================
124
+ Also see example Jupyter Notebooks here: https://github.com/Thomasjkeel/RainfallQC-notebooks/tree/main
125
+
126
+ Documents
127
+ ---------
128
+ * Free software: GNU General Public License v3
129
+ * Documentation: https://rainfallqc.readthedocs.io.
130
+
131
+
132
+ Features
133
+ --------
134
+
135
+ - 25 rainfall QC methods (all from IntenseQC)
136
+ - editable parameters so you can tweak thresholds, streak or accumulation lengths, and distances to neighbouring gauges
137
+
138
+ Credits
139
+ -------
140
+ Based on the IntenseQC: https://github.com/nclwater/intense-qc/tree/master
141
+
142
+
143
+ This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
144
+
145
+ .. _Cookiecutter: https://github.com/audreyr/cookiecutter
146
+ .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
@@ -0,0 +1,158 @@
1
+ [build-system]
2
+ requires = ["flit_core >=3.4"]
3
+ build-backend = "flit_core.buildapi"
4
+
5
+ [project]
6
+ name = "rainfallqc"
7
+ dynamic = ["version"]
8
+ description = "Quality control for rainfall data"
9
+ readme = "README.rst"
10
+ requires-python = ">=3.10.0"
11
+ authors = [{ name = "Tom Keel", email = "tomkee@ceh.ac.uk" }]
12
+ maintainers = [{ name = "Tom Keel", email = "tomkee@ceh.ac.uk" }]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "Intended Audience :: Science/Research",
17
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
18
+ "Natural Language :: English",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Scientific/Engineering :: Hydrology",
26
+ ]
27
+ license = { file = "LICENSE" }
28
+ dependencies = [
29
+ "scipy",
30
+ "numpy",
31
+ "polars",
32
+ "pandas",
33
+ "xarray",
34
+ "bottleneck",
35
+ "geopy"
36
+ ]
37
+
38
+ [project.optional-dependencies]
39
+ test = ["pytest", "pytest-cov"]
40
+ docs = ["sphinx", "sphinx-copybutton", "sphinx-rtd-theme"]
41
+ lint = ["mypy", "ruff"]
42
+ dev = [
43
+ "pip",
44
+ "numpy",
45
+ "bump-my-version",
46
+ "ruff",
47
+ "black",
48
+ "pre_commit",
49
+ "pylint",
50
+ "pytest",
51
+ "pytest-cov",
52
+ "matplotlib",
53
+ "sphinx",
54
+ ]
55
+
56
+ [project.urls]
57
+ bugs = "https://github.com/thomasjkeel/RainfallQC/issues"
58
+ changelog = "https://github.com/thomasjkeel/RainfallQC/blob/master/changelog.md"
59
+ homepage = "https://github.com/thomasjkeel/RainfallQC"
60
+
61
+ [tool]
62
+
63
+ [tool.black]
64
+ target-version = ["py310", "py311", "py312", "py313"]
65
+
66
+ [tool.bumpversion]
67
+ current_version = "0.0.9"
68
+ commit = true
69
+ message = "Bump version: {current_version} → {new_version}"
70
+ commit_args = ""
71
+ allow_dirty = false
72
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\-(?P<release>[a-z]+))?"
73
+ serialize = ["{major}.{minor}.{patch}-{release}", "{major}.{minor}.{patch}"]
74
+ search = "{current_version}"
75
+ replace = "{new_version}"
76
+ regex = false
77
+ ignore_missing_version = false
78
+ tag = false
79
+ sign_tags = false
80
+ tag_name = "v{new_version}"
81
+ tag_message = "Bump version: {current_version} → {new_version}"
82
+
83
+
84
+ [[tool.bumpversion.files]]
85
+ filename = "src/rainfallqc/__init__.py"
86
+ search = "__version__ = \"{current_version}\""
87
+ replace = "__version__ = \"{new_version}\""
88
+
89
+ [tool.bumpversion.parts.release]
90
+ optional_value = "gamma"
91
+ values = ["alpha", "beta", "gamma"]
92
+
93
+ [tool.pytest.ini_options]
94
+ addopts = "--cov=rainfallqc"
95
+ markers = ["slow: Marks slow tests"]
96
+ testpaths = ["tests"]
97
+ pythonpath = ["src"]
98
+
99
+ [tool.setuptools]
100
+ package-dir = { "src" = "src" }
101
+
102
+ [tool.setuptools.package-data]
103
+ "rainfallqc" = ["data/ETCCDI/*.nc"]
104
+
105
+ [tool.coverage.run]
106
+ omit = ["tests/*.py", "*__init__.py"]
107
+ relative_files = true
108
+
109
+ [tool.ruff]
110
+ src = ["src", "tests"]
111
+ include = ["src/**.py"]
112
+ line-length = 120
113
+
114
+ [tool.ruff.lint]
115
+ ignore = [
116
+ "D203", # incorrect-blank-line-before-class
117
+ "D212", # multi-line-summary-first-line
118
+ ]
119
+ preview = true
120
+ select = [
121
+ "A",
122
+ "B", # bugbear
123
+ "D", # docstrings
124
+ "E", # pycodestyle errors
125
+ "F", # pyflakes
126
+ "I", # imports
127
+ "W", # pycodestyle warnings
128
+ "PLC",
129
+ "PLE",
130
+ "PLW",
131
+ "N816",
132
+ "ANN001",
133
+ "ANN201",
134
+ "ANN202",
135
+ "ANN205",
136
+ "ANN206", # TODO
137
+ ]
138
+ exclude = ["docs/conf.py", "docs/notebooks/*.ipynb"]
139
+
140
+ [tool.ruff.lint.flake8-type-checking]
141
+ strict = true
142
+
143
+ [tool.ruff.lint.isort]
144
+ case-sensitive = true
145
+
146
+ [tool.ruff.lint.per-file-ignores]
147
+ "tests/*.py" = [
148
+ "ANN001", "ANN201", "ANN202", # Missing type annotation
149
+ "D103" # Missing docstring in public function
150
+ ]
151
+
152
+ [tool.mypy]
153
+ files = "."
154
+
155
+ # Use strict defaults
156
+ strict = true
157
+ warn_unreachable = true
158
+ warn_no_return = true
@@ -0,0 +1,22 @@
1
+ """Top-level package for RainfallQC."""
2
+
3
+ __author__ = """Tom Keel"""
4
+ __email__ = "tomkee@ceh.ac.uk"
5
+ __version__ = "0.0.9"
6
+
7
+ from rainfallqc.checks import (
8
+ comparison_checks,
9
+ gauge_checks,
10
+ neighbourhood_checks,
11
+ timeseries_checks,
12
+ )
13
+ from rainfallqc.qc_frameworks import apply_qc_framework
14
+
15
+ __all__ = [
16
+ "apply_qc_framework",
17
+ "comparison_checks",
18
+ "gauge_checks",
19
+ "neighbourhood_checks",
20
+ "timeseries_checks",
21
+ "apply_qc_framework",
22
+ ]
@@ -0,0 +1 @@
1
+ """Quality checks."""