oafuncs 0.0.98.0__py3-none-any.whl → 0.0.98.2__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.
- oafuncs/_script/netcdf_write.py +69 -78
- oafuncs/oa_down/idm.py +2 -1
- oafuncs/oa_nc.py +2 -2
- {oafuncs-0.0.98.0.dist-info → oafuncs-0.0.98.2.dist-info}/METADATA +1 -1
- {oafuncs-0.0.98.0.dist-info → oafuncs-0.0.98.2.dist-info}/RECORD +8 -8
- {oafuncs-0.0.98.0.dist-info → oafuncs-0.0.98.2.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.98.0.dist-info → oafuncs-0.0.98.2.dist-info}/licenses/LICENSE.txt +0 -0
- {oafuncs-0.0.98.0.dist-info → oafuncs-0.0.98.2.dist-info}/top_level.txt +0 -0
oafuncs/_script/netcdf_write.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import numpy as np
|
2
1
|
import os
|
3
2
|
import netCDF4 as nc
|
3
|
+
import numpy as np
|
4
4
|
import xarray as xr
|
5
5
|
|
6
6
|
|
@@ -18,108 +18,99 @@ def _numpy_to_nc_type(numpy_type):
|
|
18
18
|
"uint32": "u4",
|
19
19
|
"uint64": "u8",
|
20
20
|
}
|
21
|
-
# 确保传入的是字符串类型,如果不是,则转换为字符串
|
22
21
|
numpy_type_str = str(numpy_type) if not isinstance(numpy_type, str) else numpy_type
|
23
|
-
return numpy_to_nc.get(numpy_type_str, "f4")
|
22
|
+
return numpy_to_nc.get(numpy_type_str, "f4")
|
24
23
|
|
25
24
|
|
26
25
|
def _calculate_scale_and_offset(data, n=16):
|
27
26
|
if not isinstance(data, np.ndarray):
|
28
27
|
raise ValueError("Input data must be a NumPy array.")
|
29
28
|
|
30
|
-
# 使用 nan_to_num 来避免 NaN 值对 min 和 max 的影响
|
31
29
|
data_min = np.nanmin(data)
|
32
30
|
data_max = np.nanmax(data)
|
33
31
|
|
34
32
|
if np.isnan(data_min) or np.isnan(data_max):
|
35
|
-
raise ValueError("Input data contains NaN values
|
33
|
+
raise ValueError("Input data contains NaN values.")
|
36
34
|
|
37
35
|
scale_factor = (data_max - data_min) / (2**n - 1)
|
38
36
|
add_offset = data_min + 2 ** (n - 1) * scale_factor
|
39
|
-
|
40
37
|
return scale_factor, add_offset
|
41
38
|
|
42
39
|
|
43
40
|
def save_to_nc(file, data, varname=None, coords=None, mode="w", scale_offset_switch=True, compile_switch=True):
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
41
|
+
# 处理xarray对象的情况(当varname和coords都为None时)
|
42
|
+
if varname is None and coords is None:
|
43
|
+
if not isinstance(data, (xr.DataArray, xr.Dataset)):
|
44
|
+
raise ValueError("When varname and coords are not provided, data must be an xarray object")
|
45
|
+
|
46
|
+
encoding = {}
|
47
|
+
if isinstance(data, xr.DataArray):
|
48
|
+
if data.name is None:
|
49
|
+
data = data.rename("data")
|
50
|
+
varname = data.name
|
51
|
+
encoding[varname] = {"zlib": compile_switch, "complevel": 4}
|
52
|
+
if scale_offset_switch:
|
53
|
+
scale, offset = _calculate_scale_and_offset(data.values)
|
54
|
+
encoding[varname].update({"dtype": "int16", "scale_factor": scale, "add_offset": offset, "_FillValue": -32767})
|
55
|
+
else:
|
56
|
+
encoding[varname].update({"dtype": "float32", "_FillValue": np.nan})
|
57
|
+
else: # Dataset情况
|
58
|
+
for var in data.data_vars:
|
59
|
+
encoding[var] = {"zlib": compile_switch, "complevel": 4}
|
60
|
+
if scale_offset_switch:
|
61
|
+
scale, offset = _calculate_scale_and_offset(data[var].values)
|
62
|
+
encoding[var].update({"dtype": "int16", "scale_factor": scale, "add_offset": offset, "_FillValue": -32767})
|
63
|
+
else:
|
64
|
+
encoding[var].update({"dtype": "float32", "_FillValue": np.nan})
|
65
|
+
|
66
|
+
try:
|
67
|
+
data.to_netcdf(file, mode=mode, encoding=encoding)
|
68
|
+
return
|
69
|
+
except Exception as e:
|
70
|
+
raise RuntimeError(f"Failed to save xarray object: {str(e)}") from e
|
71
|
+
|
72
|
+
# 处理普通numpy数组的情况
|
62
73
|
if mode == "w" and os.path.exists(file):
|
63
74
|
os.remove(file)
|
64
75
|
elif mode == "a" and not os.path.exists(file):
|
65
76
|
mode = "w"
|
66
77
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
"complevel": 4,
|
77
|
-
"dtype": "int16",
|
78
|
-
"scale_factor": scale_factor,
|
79
|
-
"add_offset": add_offset,
|
80
|
-
"_FillValue": -32767,
|
81
|
-
}
|
82
|
-
data.to_netcdf(file, mode=mode, encoding=encoding)
|
83
|
-
return
|
78
|
+
try:
|
79
|
+
with nc.Dataset(file, mode, format="NETCDF4") as ncfile:
|
80
|
+
# 创建维度并写入坐标
|
81
|
+
if coords is not None:
|
82
|
+
for dim, values in coords.items():
|
83
|
+
if dim not in ncfile.dimensions:
|
84
|
+
ncfile.createDimension(dim, len(values))
|
85
|
+
var = ncfile.createVariable(dim, _numpy_to_nc_type(values.dtype), (dim,))
|
86
|
+
var[:] = values
|
84
87
|
|
85
|
-
# 添加坐标
|
86
|
-
for dim, coord_data in coords.items():
|
87
|
-
if dim in ncfile.dimensions:
|
88
|
-
if len(coord_data) != len(ncfile.dimensions[dim]):
|
89
|
-
raise ValueError(f"Length of coordinate '{dim}' does not match the dimension length.")
|
90
|
-
else:
|
91
|
-
ncfile.variables[dim][:] = np.array(coord_data)
|
92
|
-
else:
|
93
|
-
ncfile.createDimension(dim, len(coord_data))
|
94
|
-
var = ncfile.createVariable(dim, _numpy_to_nc_type(coord_data.dtype), (dim,), **kwargs)
|
95
|
-
var[:] = np.array(coord_data)
|
96
|
-
|
97
|
-
# 如果坐标数据有属性,则添加到 NetCDF 变量
|
98
|
-
if isinstance(coord_data, xr.DataArray) and coord_data.attrs:
|
99
|
-
for attr_name, attr_value in coord_data.attrs.items():
|
100
|
-
var.setncattr(attr_name, attr_value)
|
101
|
-
|
102
|
-
# 添加或更新变量
|
103
|
-
if varname in ncfile.variables:
|
104
|
-
if data.shape != ncfile.variables[varname].shape:
|
105
|
-
raise ValueError(f"Shape of data does not match the variable shape for '{varname}'.")
|
106
|
-
ncfile.variables[varname][:] = np.array(data)
|
107
|
-
else:
|
108
88
|
# 创建变量
|
109
|
-
|
89
|
+
dims = list(coords.keys()) if coords else []
|
110
90
|
if scale_offset_switch:
|
111
|
-
|
112
|
-
|
113
|
-
var =
|
114
|
-
var.
|
115
|
-
var.setncattr("add_offset", add_offset)
|
91
|
+
scale, offset = _calculate_scale_and_offset(data)
|
92
|
+
var = ncfile.createVariable(varname, "i2", dims, fill_value=-32767, zlib=compile_switch)
|
93
|
+
var.scale_factor = scale
|
94
|
+
var.add_offset = offset
|
116
95
|
else:
|
117
96
|
dtype = _numpy_to_nc_type(data.dtype)
|
118
|
-
var = ncfile.createVariable(varname, dtype,
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
97
|
+
var = ncfile.createVariable(varname, dtype, dims, zlib=compile_switch)
|
98
|
+
|
99
|
+
var[:] = data
|
100
|
+
except Exception as e:
|
101
|
+
raise RuntimeError(f"Failed to save netCDF4 file: {str(e)}") from e
|
102
|
+
|
103
|
+
|
104
|
+
if __name__ == "__main__":
|
105
|
+
# Example usage
|
106
|
+
data = xr.open_dataset(r"F:\roms_rst.nc")["u"]
|
107
|
+
save_to_nc(r"F:\test.nc", data)
|
108
|
+
|
109
|
+
# xarray测试
|
110
|
+
data = xr.DataArray(np.random.rand(10, 20), dims=("x", "y"), name="temperature")
|
111
|
+
save_to_nc(r"F:\test_xarray.nc", data)
|
112
|
+
|
113
|
+
# numpy测试
|
114
|
+
arr = np.random.rand(5, 3)
|
115
|
+
coords = {"x": np.arange(5), "y": np.arange(3)}
|
116
|
+
save_to_nc(r"F:\test_numpy.nc", arr, varname="data", coords=coords)
|
oafuncs/oa_down/idm.py
CHANGED
@@ -52,6 +52,7 @@ def downloader(task_url, folder_path, file_name, idm_engine=r"D:\Programs\Intern
|
|
52
52
|
time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
53
53
|
time_str = time_str.center(100, " ")
|
54
54
|
print(f"[bold purple]{time_str}")
|
55
|
-
|
55
|
+
info = f'IDM Downloader: {file_name}'.center(100, " ")
|
56
|
+
print(f"[green]{info}[/green]")
|
56
57
|
print("[purple]*" * 100)
|
57
58
|
# print("\n")
|
oafuncs/oa_nc.py
CHANGED
@@ -11,7 +11,7 @@ __all__ = ["save", "merge", "modify", "rename", "check", "convert_longitude", "i
|
|
11
11
|
|
12
12
|
def save(
|
13
13
|
file_path: str,
|
14
|
-
data: Union[np.ndarray, xr.DataArray],
|
14
|
+
data: Union[np.ndarray, xr.DataArray, xr.Dataset],
|
15
15
|
variable_name: Optional[str] = None,
|
16
16
|
coordinates: Optional[dict] = None,
|
17
17
|
write_mode: str = "w",
|
@@ -23,7 +23,7 @@ def save(
|
|
23
23
|
|
24
24
|
Args:
|
25
25
|
file_path (str): File path to save the NetCDF file.
|
26
|
-
data (Union[np.ndarray, xr.DataArray]): Data to be written.
|
26
|
+
data (Union[np.ndarray, xr.DataArray, xr.Dataset]): Data to be written.
|
27
27
|
variable_name (Optional[str]): Variable name for the data.
|
28
28
|
coordinates (Optional[dict]): Coordinates, where keys are dimension names and values are coordinate data.
|
29
29
|
write_mode (str): Write mode, 'w' for write, 'a' for append. Default is 'w'.
|
@@ -5,7 +5,7 @@ oafuncs/oa_date.py,sha256=KqU-bHtC74hYsf6VgiA3i2vI__q_toOVR-whFy4cYP8,5523
|
|
5
5
|
oafuncs/oa_draw.py,sha256=9hchfs7kyBo_On1FA5jliSoAwpsjEXNUIC9C20D9ugw,15050
|
6
6
|
oafuncs/oa_file.py,sha256=goF5iRXJFFCIKhIjlkCnYYt0EYlJb_4r8AeYNZ0-SOk,16209
|
7
7
|
oafuncs/oa_help.py,sha256=_4AZgRDq5Or0vauNvq5IDDHIBoBfdOQtzak-mG1wwAw,4537
|
8
|
-
oafuncs/oa_nc.py,sha256=
|
8
|
+
oafuncs/oa_nc.py,sha256=L1gqXxg93kIDsMOa87M0o-53KVmdqCipnXeF9XfzfY8,10513
|
9
9
|
oafuncs/oa_python.py,sha256=NkopwkYFGSEuVljnTBvXCl6o2CeyRNBqRXSsUl3euEE,5192
|
10
10
|
oafuncs/oa_tool.py,sha256=8y0X3KXNLbYchr5hBHCwhdsA_1VDEnzsZVqcM5sNeog,4484
|
11
11
|
oafuncs/_data/hycom.png,sha256=MadKs6Gyj5n9-TOu7L4atQfTXtF9dvN9w-tdU9IfygI,10945710
|
@@ -14,7 +14,7 @@ oafuncs/_script/cprogressbar.py,sha256=wRU3SFPFtMI7ER26tTzg223kVKNo5RDWE9CzdIgUs
|
|
14
14
|
oafuncs/_script/email.py,sha256=lL4HGKrr524-g0xLlgs-4u7x4-u7DtgNoD9AL8XJKj4,3058
|
15
15
|
oafuncs/_script/netcdf_merge.py,sha256=_EPF9Xj4HOVC9sZpi1lt62-Aq6pMlgsgwaajEBLhW6g,5092
|
16
16
|
oafuncs/_script/netcdf_modify.py,sha256=sGRUYNhfGgf9JV70rnBzw3bzuTRSXzBTL_RMDnDPeLQ,4552
|
17
|
-
oafuncs/_script/netcdf_write.py,sha256=
|
17
|
+
oafuncs/_script/netcdf_write.py,sha256=8bVsJKRPLWJawUTAsMUiG5D9lOg_-sRMgshgtRjo_us,4598
|
18
18
|
oafuncs/_script/parallel.py,sha256=FS9FgaByq2yb9j6nL-Y0xP1VLvp4USMLBFMRsJDoqeQ,21848
|
19
19
|
oafuncs/_script/parallel_example_usage.py,sha256=uLvE7iwkMn9Cyq6-wk5_RpbQk7PXM9d16-26lTknW9s,2646
|
20
20
|
oafuncs/_script/plot_dataset.py,sha256=zkSEnO_-biyagorwWXPoihts_cwuvripzEt-l9bHJ2E,13989
|
@@ -23,7 +23,7 @@ oafuncs/oa_down/User_Agent-list.txt,sha256=pazxSip8_lphEBOPHG902zmIBUg8sBKXgmqp_
|
|
23
23
|
oafuncs/oa_down/__init__.py,sha256=kRX5eTUCbAiz3zTaQM1501paOYS_3fizDN4Pa0mtNUA,585
|
24
24
|
oafuncs/oa_down/hycom_3hourly.py,sha256=Xi6LuD3DIiYq2gYYBVxY3OpVvfy3RkSMzNkOX2isSK8,52915
|
25
25
|
oafuncs/oa_down/hycom_3hourly_20250407.py,sha256=DQd_NmQgmSqu7jsrfpDB7k23mkUEy9kyWs-dLUg7GDw,64472
|
26
|
-
oafuncs/oa_down/idm.py,sha256=
|
26
|
+
oafuncs/oa_down/idm.py,sha256=4z5IvgfTyIKEI1kOtqXZwN7Jnfjwp6qDBOIoVyOLp0I,1823
|
27
27
|
oafuncs/oa_down/literature.py,sha256=2bF9gSKQbzcci9LcKE81j8JEjIJwON7jbwQB3gDDA3E,11331
|
28
28
|
oafuncs/oa_down/test_ua.py,sha256=0IQq3NjqfNr7KkyjS_U-a4mYu-r-E7gzawwo4IfEa6Y,10851
|
29
29
|
oafuncs/oa_down/user_agent.py,sha256=TsPcAxFmMTYAEHRFjurI1bQBJfDhcA70MdHoUPwQmks,785
|
@@ -36,8 +36,8 @@ oafuncs/oa_sign/__init__.py,sha256=QKqTFrJDFK40C5uvk48GlRRbGFzO40rgkYwu6dYxatM,5
|
|
36
36
|
oafuncs/oa_sign/meteorological.py,sha256=8091SHo2L8kl4dCFmmSH5NGVHDku5i5lSiLEG5DLnOQ,6489
|
37
37
|
oafuncs/oa_sign/ocean.py,sha256=xrW-rWD7xBWsB5PuCyEwQ1Q_RDKq2KCLz-LOONHgldU,5932
|
38
38
|
oafuncs/oa_sign/scientific.py,sha256=a4JxOBgm9vzNZKpJ_GQIQf7cokkraV5nh23HGbmTYKw,5064
|
39
|
-
oafuncs-0.0.98.
|
40
|
-
oafuncs-0.0.98.
|
41
|
-
oafuncs-0.0.98.
|
42
|
-
oafuncs-0.0.98.
|
43
|
-
oafuncs-0.0.98.
|
39
|
+
oafuncs-0.0.98.2.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
|
40
|
+
oafuncs-0.0.98.2.dist-info/METADATA,sha256=2-IktPjhTVHt-GLLgJk7J2tYMBYaNA0eY7IZyB0kxlk,4220
|
41
|
+
oafuncs-0.0.98.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
42
|
+
oafuncs-0.0.98.2.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
|
43
|
+
oafuncs-0.0.98.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|