climarraykit 0.2.0__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.
- climarraykit-0.2.0/CHANGELOG.md +41 -0
- climarraykit-0.2.0/LICENSE +21 -0
- climarraykit-0.2.0/MANIFEST.in +6 -0
- climarraykit-0.2.0/PKG-INFO +86 -0
- climarraykit-0.2.0/README.md +24 -0
- climarraykit-0.2.0/climarraykit/__init__.py +12 -0
- climarraykit-0.2.0/climarraykit/conversions.py +208 -0
- climarraykit-0.2.0/climarraykit/data_manipulation.py +386 -0
- climarraykit-0.2.0/climarraykit/file_utils.py +309 -0
- climarraykit-0.2.0/climarraykit/patterns.py +616 -0
- climarraykit-0.2.0/climarraykit/xarray_obj_handler.py +575 -0
- climarraykit-0.2.0/climarraykit.egg-info/PKG-INFO +86 -0
- climarraykit-0.2.0/climarraykit.egg-info/SOURCES.txt +18 -0
- climarraykit-0.2.0/climarraykit.egg-info/dependency_links.txt +1 -0
- climarraykit-0.2.0/climarraykit.egg-info/requires.txt +19 -0
- climarraykit-0.2.0/climarraykit.egg-info/top_level.txt +1 -0
- climarraykit-0.2.0/pyproject.toml +87 -0
- climarraykit-0.2.0/requirements-dev.txt +5 -0
- climarraykit-0.2.0/requirements.txt +7 -0
- climarraykit-0.2.0/setup.cfg +4 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# climarraykit Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [0.2.0] - 2026-03-31
|
|
8
|
+
|
|
9
|
+
### Changed (0.2.0)
|
|
10
|
+
|
|
11
|
+
#### **Package Dependencies** (changing; 0.2.0)
|
|
12
|
+
|
|
13
|
+
- **NumPy / Pandas:** require **`numpy>=2.2.3`** and **`pandas>=2.2.3`** in **`pyproject.toml`**, **`requirements.txt`**, and **`recipe/meta.yaml`**.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## [0.1.0] - 2026-03-30
|
|
18
|
+
|
|
19
|
+
### Added (0.1.0)
|
|
20
|
+
|
|
21
|
+
- Bootstrap dedicated package metadata:
|
|
22
|
+
- `pyproject.toml`
|
|
23
|
+
- `LICENSE`
|
|
24
|
+
- `MANIFEST.in`
|
|
25
|
+
- `requirements.txt`
|
|
26
|
+
- `requirements-dev.txt`
|
|
27
|
+
- `README.md`
|
|
28
|
+
- package `climarraykit/`
|
|
29
|
+
|
|
30
|
+
- Introduce initial xarray-focused module surface:
|
|
31
|
+
- `climarraykit.file_utils`
|
|
32
|
+
- `climarraykit.patterns`
|
|
33
|
+
- `climarraykit.conversions`
|
|
34
|
+
- `climarraykit.data_manipulation`
|
|
35
|
+
- `climarraykit.xarray_obj_handler`
|
|
36
|
+
|
|
37
|
+
- Provide a non-breaking migration path by preserving the legacy logic and API shape while
|
|
38
|
+
enabling import migration towards `climarraykit`.
|
|
39
|
+
|
|
40
|
+
- Add `rename_xarray_dimension` to `climarraykit.patterns` for robust xarray dimension
|
|
41
|
+
renaming (shared by downstream packages such as `statflow` climatology helpers).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 climarraykit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: climarraykit
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Climate-focused xarray toolkit for NetCDF/GRIB handling, coordinate discovery, and dataset serialisation
|
|
5
|
+
Author-email: Jon Ander Gabantxo <jagabantxo@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 climarraykit
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/EusDancerDev/climarraykit
|
|
29
|
+
Project-URL: Documentation, https://github.com/EusDancerDev/climarraykit#readme
|
|
30
|
+
Project-URL: Repository, https://github.com/EusDancerDev/climarraykit.git
|
|
31
|
+
Project-URL: Bug Reports, https://github.com/EusDancerDev/climarraykit/issues
|
|
32
|
+
Keywords: xarray,climate,netcdf,grib,meteorology,climatology
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Intended Audience :: Science/Research
|
|
35
|
+
Classifier: Programming Language :: Python :: 3
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Operating System :: OS Independent
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
41
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
42
|
+
Requires-Python: >=3.10
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: numpy>=2.2.3
|
|
46
|
+
Requires-Dist: pandas>=2.2.3
|
|
47
|
+
Requires-Dist: xarray>=2024.2.0
|
|
48
|
+
Requires-Dist: filewise>=3.13.0
|
|
49
|
+
Requires-Dist: pygenutils>=16.4.0
|
|
50
|
+
Requires-Dist: paramlib>=3.4.10
|
|
51
|
+
Provides-Extra: grib
|
|
52
|
+
Requires-Dist: cfgrib>=0.9.10; extra == "grib"
|
|
53
|
+
Provides-Extra: regrid
|
|
54
|
+
Requires-Dist: xesmf>=0.8.0; extra == "regrid"
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
57
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
58
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
59
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
60
|
+
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
|
61
|
+
Dynamic: license-file
|
|
62
|
+
|
|
63
|
+
# climarraykit
|
|
64
|
+
|
|
65
|
+
`climarraykit` is a dedicated xarray-centric toolkit for climate and weather data workflows.
|
|
66
|
+
|
|
67
|
+
It is introduced to decouple heavy xarray/netCDF functionality from broader utility packages
|
|
68
|
+
where those dependencies are not always needed.
|
|
69
|
+
|
|
70
|
+
## Scope
|
|
71
|
+
|
|
72
|
+
- netCDF file scanning and integrity checks
|
|
73
|
+
- coordinate and dimension discovery utilities
|
|
74
|
+
- GRIB-to-netCDF conversion helpers
|
|
75
|
+
- xarray Dataset/DataArray creation and serialisation helpers
|
|
76
|
+
- climate-oriented xarray data manipulation helpers
|
|
77
|
+
|
|
78
|
+
## Transitional compatibility
|
|
79
|
+
|
|
80
|
+
This initial release preserves behaviour by exposing the same module-level APIs as the
|
|
81
|
+
legacy `filewise.xarray_utils` package while enabling downstream projects to migrate imports
|
|
82
|
+
to `climarraykit`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
Current version: **0.2.0** (see [CHANGELOG.md](CHANGELOG.md)).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# climarraykit
|
|
2
|
+
|
|
3
|
+
`climarraykit` is a dedicated xarray-centric toolkit for climate and weather data workflows.
|
|
4
|
+
|
|
5
|
+
It is introduced to decouple heavy xarray/netCDF functionality from broader utility packages
|
|
6
|
+
where those dependencies are not always needed.
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
- netCDF file scanning and integrity checks
|
|
11
|
+
- coordinate and dimension discovery utilities
|
|
12
|
+
- GRIB-to-netCDF conversion helpers
|
|
13
|
+
- xarray Dataset/DataArray creation and serialisation helpers
|
|
14
|
+
- climate-oriented xarray data manipulation helpers
|
|
15
|
+
|
|
16
|
+
## Transitional compatibility
|
|
17
|
+
|
|
18
|
+
This initial release preserves behaviour by exposing the same module-level APIs as the
|
|
19
|
+
legacy `filewise.xarray_utils` package while enabling downstream projects to migrate imports
|
|
20
|
+
to `climarraykit`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
Current version: **0.2.0** (see [CHANGELOG.md](CHANGELOG.md)).
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
#----------------#
|
|
5
|
+
# Import modules #
|
|
6
|
+
#----------------#
|
|
7
|
+
|
|
8
|
+
import xarray as xr
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
#------------------------#
|
|
12
|
+
# Import project modules #
|
|
13
|
+
#------------------------#
|
|
14
|
+
|
|
15
|
+
from climarraykit.xarray_obj_handler import _save_ds_as_nc
|
|
16
|
+
from paramlib.global_parameters import CLIMATE_FILE_EXTENSIONS
|
|
17
|
+
from pygenutils.arrays_and_lists.conversions import flatten_to_string
|
|
18
|
+
from pygenutils.arrays_and_lists.data_manipulation import flatten_list
|
|
19
|
+
from pygenutils.operative_systems.os_operations import exit_info, run_system_command
|
|
20
|
+
from pygenutils.strings.string_handler import (
|
|
21
|
+
find_substring_index,
|
|
22
|
+
get_obj_specs,
|
|
23
|
+
modify_obj_specs
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
#------------------#
|
|
27
|
+
# Define functions #
|
|
28
|
+
#------------------#
|
|
29
|
+
|
|
30
|
+
# Xarray objects #
|
|
31
|
+
#----------------#
|
|
32
|
+
|
|
33
|
+
def grib2nc(
|
|
34
|
+
grib_file_list: str | list[str],
|
|
35
|
+
on_shell: bool = False,
|
|
36
|
+
option_str: str | None = None,
|
|
37
|
+
capture_output: bool = False,
|
|
38
|
+
return_output_name: bool = False,
|
|
39
|
+
encoding: str = "utf-8",
|
|
40
|
+
shell: bool = True) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Converts a GRIB file or list of GRIB files to netCDF format. The conversion
|
|
43
|
+
can be executed either via shell commands or programmatically using xarray.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
grib_file_list : str | list[str]
|
|
48
|
+
The file path(s) of the GRIB file(s) to be converted.
|
|
49
|
+
on_shell : bool, optional
|
|
50
|
+
If True, the conversion will be handled through shell commands using
|
|
51
|
+
the 'grib_to_netcdf' tool. If False, the conversion will be done
|
|
52
|
+
programmatically using xarray.
|
|
53
|
+
option_str : str, optional
|
|
54
|
+
Additional options to pass to the shell command for 'grib_to_netcdf'.
|
|
55
|
+
This parameter is only used if 'on_shell' is set to True.
|
|
56
|
+
capture_output : bool, optional
|
|
57
|
+
Whether to capture the command output. Default is False.
|
|
58
|
+
return_output_name : bool, optional
|
|
59
|
+
Whether to return file descriptor names. Default is False.
|
|
60
|
+
encoding : str, optional
|
|
61
|
+
Encoding to use when decoding command output. Default is "utf-8".
|
|
62
|
+
shell : bool, optional
|
|
63
|
+
Whether to execute the command through the shell. Default is True.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
None
|
|
68
|
+
Converts the GRIB file(s) to netCDF format and saves the output
|
|
69
|
+
netCDF file(s) in the same directory as the GRIB files.
|
|
70
|
+
|
|
71
|
+
Raises
|
|
72
|
+
------
|
|
73
|
+
TypeError
|
|
74
|
+
If grib_file_list is not str or list of str.
|
|
75
|
+
ValueError
|
|
76
|
+
If any GRIB file path is invalid or empty.
|
|
77
|
+
FileNotFoundError
|
|
78
|
+
If any GRIB file doesn't exist.
|
|
79
|
+
|
|
80
|
+
Notes
|
|
81
|
+
-----
|
|
82
|
+
- When 'on_shell' is True, the function builds and runs a shell command
|
|
83
|
+
that calls the 'grib_to_netcdf' tool, with optional flags.
|
|
84
|
+
- When 'on_shell' is False, xarray is used to directly open the GRIB file
|
|
85
|
+
and convert it to netCDF format.
|
|
86
|
+
- The function will prompt for input in the case of multiple GRIB files if
|
|
87
|
+
'on_shell' is True.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
# Parameter validation
|
|
91
|
+
if not isinstance(grib_file_list, (str, list)):
|
|
92
|
+
raise TypeError("grib_file_list must be a string or list of strings")
|
|
93
|
+
|
|
94
|
+
# Flatten nested lists for defensive programming
|
|
95
|
+
if isinstance(grib_file_list, list):
|
|
96
|
+
grib_file_list = flatten_list(grib_file_list)
|
|
97
|
+
|
|
98
|
+
# Validate all items are strings
|
|
99
|
+
if not all(isinstance(item, str) for item in grib_file_list):
|
|
100
|
+
raise TypeError("All items in grib_file_list must be strings")
|
|
101
|
+
|
|
102
|
+
# Check for empty strings
|
|
103
|
+
if not all(item.strip() for item in grib_file_list):
|
|
104
|
+
raise ValueError("All GRIB file paths must be non-empty strings")
|
|
105
|
+
else:
|
|
106
|
+
# Single string validation
|
|
107
|
+
if not isinstance(grib_file_list, str) or not grib_file_list.strip():
|
|
108
|
+
raise ValueError("GRIB file path must be a non-empty string")
|
|
109
|
+
|
|
110
|
+
# Check file existence
|
|
111
|
+
files_to_check = [grib_file_list] if isinstance(grib_file_list, str) else grib_file_list
|
|
112
|
+
for grib_file in files_to_check:
|
|
113
|
+
if not Path(grib_file).exists():
|
|
114
|
+
raise FileNotFoundError(f"GRIB file not found: {grib_file}")
|
|
115
|
+
|
|
116
|
+
# Check if file has expected GRIB extension
|
|
117
|
+
if not any(grib_file.lower().endswith(ext.lower()) for ext in ['.grib', '.grb', '.grib2', '.grb2']):
|
|
118
|
+
print(f"Warning: File {grib_file} may not be a GRIB file based on extension")
|
|
119
|
+
|
|
120
|
+
# Shell-based conversion #
|
|
121
|
+
#-#-#-#-#-#-#-#-#-#-#-#-#
|
|
122
|
+
|
|
123
|
+
if on_shell:
|
|
124
|
+
# Handle single GRIB file
|
|
125
|
+
if isinstance(grib_file_list, str):
|
|
126
|
+
nc_file_new = modify_obj_specs(grib_file_list, "ext", EXTENSIONS[0])
|
|
127
|
+
|
|
128
|
+
# Handle list of GRIB files
|
|
129
|
+
else:
|
|
130
|
+
grib_allfile_info_str = flatten_to_string(grib_file_list)
|
|
131
|
+
|
|
132
|
+
# Prompt user for the netCDF file name without extension
|
|
133
|
+
nc_file_new_noext = input("Please introduce a name "
|
|
134
|
+
"for the netCDF file, "
|
|
135
|
+
"WITHOUT THE EXTENSION: ")
|
|
136
|
+
|
|
137
|
+
# Validate the file name using RegEx
|
|
138
|
+
allowed_minimum_char_idx = find_substring_index(nc_file_new_noext,
|
|
139
|
+
REGEX_GRIB2NC,
|
|
140
|
+
advanced_search=True)
|
|
141
|
+
|
|
142
|
+
while allowed_minimum_char_idx == -1:
|
|
143
|
+
print("Invalid file name.\nIt can contain alphanumeric characters, "
|
|
144
|
+
"as well as the following non-word characters: {. _ -}")
|
|
145
|
+
nc_file_new_noext = input("Please introduce a valid name: ")
|
|
146
|
+
allowed_minimum_char_idx = find_substring_index(nc_file_new_noext,
|
|
147
|
+
REGEX_GRIB2NC,
|
|
148
|
+
advanced_search=True)
|
|
149
|
+
|
|
150
|
+
# Modify the file name to have the .nc extension
|
|
151
|
+
nc_file_new = modify_obj_specs(nc_file_new_noext,
|
|
152
|
+
obj2modify="ext",
|
|
153
|
+
new_obj=EXTENSIONS[0])
|
|
154
|
+
|
|
155
|
+
# Construct the shell command for conversion
|
|
156
|
+
grib2nc_template = "grib_to_netcdf "
|
|
157
|
+
if option_str:
|
|
158
|
+
grib2nc_template += f"{option_str} "
|
|
159
|
+
grib2nc_template += f"-o {nc_file_new} {grib_allfile_info_str}"
|
|
160
|
+
|
|
161
|
+
# Execute the shell command
|
|
162
|
+
try:
|
|
163
|
+
process_exit_info = run_system_command(
|
|
164
|
+
grib2nc_template,
|
|
165
|
+
capture_output=capture_output,
|
|
166
|
+
return_output_name=return_output_name,
|
|
167
|
+
encoding=encoding,
|
|
168
|
+
shell=shell
|
|
169
|
+
)
|
|
170
|
+
# Call exit_info with parameters based on capture_output
|
|
171
|
+
exit_info(
|
|
172
|
+
process_exit_info,
|
|
173
|
+
check_stdout=True,
|
|
174
|
+
check_stderr=True,
|
|
175
|
+
check_return_code=True
|
|
176
|
+
)
|
|
177
|
+
except Exception as e:
|
|
178
|
+
raise RuntimeError(f"Shell command execution failed: {e}")
|
|
179
|
+
|
|
180
|
+
# Programmatic conversion #
|
|
181
|
+
#-#-#-#-#-#-#-#-#-#-#-#-#-#
|
|
182
|
+
|
|
183
|
+
else:
|
|
184
|
+
# Ensure grib_file_list is a list
|
|
185
|
+
if isinstance(grib_file_list, str):
|
|
186
|
+
grib_file_list = [grib_file_list]
|
|
187
|
+
|
|
188
|
+
# Convert each GRIB file in the list to netCDF
|
|
189
|
+
for grib_file in grib_file_list:
|
|
190
|
+
try:
|
|
191
|
+
grib_file_noext = get_obj_specs(grib_file, "name_noext", EXTENSIONS[0])
|
|
192
|
+
ds = xr.open_dataset(grib_file, engine="cfgrib")
|
|
193
|
+
_save_ds_as_nc(ds, grib_file_noext)
|
|
194
|
+
print(f"Successfully converted {grib_file} to netCDF format")
|
|
195
|
+
except Exception as e:
|
|
196
|
+
print(f"Error converting {grib_file}: {e}")
|
|
197
|
+
raise
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
#--------------------------#
|
|
201
|
+
# Parameters and constants #
|
|
202
|
+
#--------------------------#
|
|
203
|
+
|
|
204
|
+
# Valid file extensions #
|
|
205
|
+
EXTENSIONS = CLIMATE_FILE_EXTENSIONS[::3]
|
|
206
|
+
|
|
207
|
+
# RegEx control for GRIB-to-netCDF single file name #
|
|
208
|
+
REGEX_GRIB2NC = r"^[a-zA-Z\d\._-]$"
|