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.
@@ -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") # 默认使用 'float32'
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, which are not allowed.")
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
- Description:
46
- Write data to NetCDF file
47
- Parameters:
48
- file: str, file path
49
- data: data
50
- varname: str, variable name
51
- coords: dict, coordinates, key is the dimension name, value is the coordinate data
52
- mode: str, write mode, 'w' for write, 'a' for append
53
- scale_offset_switch: bool, whether to use scale_factor and add_offset, default is True
54
- compile_switch: bool, whether to use compression parameters, default is True
55
- Example:
56
- save(r'test.nc', data, 'u', {'time': np.linspace(0, 120, 100), 'lev': np.linspace(0, 120, 50)}, 'a')
57
- """
58
- # 设置压缩参数
59
- kwargs = {"zlib": True, "complevel": 4} if compile_switch else {}
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
- # 打开 NetCDF 文件
68
- with nc.Dataset(file, mode, format="NETCDF4") as ncfile:
69
- # 如果 data 是 DataArray 并且没有提供 varname 和 coords
70
- if varname is None and coords is None and isinstance(data, xr.DataArray):
71
- encoding = {}
72
- for var in data.data_vars:
73
- scale_factor, add_offset = _calculate_scale_and_offset(data[var].values)
74
- encoding[var] = {
75
- "zlib": True,
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
- dim_names = tuple(coords.keys())
89
+ dims = list(coords.keys()) if coords else []
110
90
  if scale_offset_switch:
111
- scale_factor, add_offset = _calculate_scale_and_offset(np.array(data))
112
- dtype = "i2"
113
- var = ncfile.createVariable(varname, dtype, dim_names, fill_value=-32767, **kwargs)
114
- var.setncattr("scale_factor", scale_factor)
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, dim_names, **kwargs)
119
- var[:] = np.array(data)
120
-
121
- # 添加属性
122
- if isinstance(data, xr.DataArray) and data.attrs:
123
- for key, value in data.attrs.items():
124
- if key not in ["scale_factor", "add_offset", "_FillValue", "missing_value"] or not scale_offset_switch:
125
- var.setncattr(key, value)
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
- print(f"[green]IDM Downloader: {file_name}[/green]".center(100, " "))
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'.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.98.0
3
+ Version: 0.0.98.2
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -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=StkcZZYo6FKANuPcq7OaIKoBKj5HuFwHsrZRVKa4ULw,10489
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=KZ0ui2nvTujAciLKx4bwQHLEkH1R3P8hCzd7BysJ0D4,5288
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=gZHyUJMyd9zgzZGksI-BuNuouK_JGjxQZniUgUFENPs,1801
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.0.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
40
- oafuncs-0.0.98.0.dist-info/METADATA,sha256=EVqN2an2LrePsPwvCK_OTDtX6Vc5mJMECkLjbDMlmC8,4220
41
- oafuncs-0.0.98.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
42
- oafuncs-0.0.98.0.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
43
- oafuncs-0.0.98.0.dist-info/RECORD,,
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,,