ncftools 0.1.0__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.
- ncftools/__init__.py +14 -0
- ncftools/cli.py +39 -0
- ncftools/describe.py +50 -0
- ncftools/meshinfo.py +100 -0
- ncftools/tests/__init__.py +0 -0
- ncftools-0.1.0.dist-info/METADATA +51 -0
- ncftools-0.1.0.dist-info/RECORD +10 -0
- ncftools-0.1.0.dist-info/WHEEL +5 -0
- ncftools-0.1.0.dist-info/entry_points.txt +4 -0
- ncftools-0.1.0.dist-info/top_level.txt +1 -0
ncftools/__init__.py
ADDED
ncftools/cli.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Top-level `ncftools` command. Running `ncftools -h` (or with no arguments)
|
|
4
|
+
prints the same information shown by `ncftools-info`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from . import describe
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _print_info(tool=None):
|
|
13
|
+
argv_backup = sys.argv
|
|
14
|
+
try:
|
|
15
|
+
sys.argv = ['ncftools-info'] + ([tool] if tool else [])
|
|
16
|
+
describe.main()
|
|
17
|
+
finally:
|
|
18
|
+
sys.argv = argv_backup
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
args = sys.argv[1:]
|
|
23
|
+
|
|
24
|
+
if not args or args[0] in ('-h', '--help'):
|
|
25
|
+
_print_info()
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
tool = args[0]
|
|
29
|
+
if tool in describe.TOOL_DESCRIPTIONS:
|
|
30
|
+
_print_info(tool)
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
print(f"Unknown option or tool: {tool}", file=sys.stderr)
|
|
34
|
+
print("Run 'ncftools -h' to see available tools.", file=sys.stderr)
|
|
35
|
+
sys.exit(2)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
main()
|
ncftools/describe.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Command-line utility to display descriptions of ncftools functionality.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
from textwrap import dedent
|
|
8
|
+
|
|
9
|
+
TOOL_DESCRIPTIONS = {
|
|
10
|
+
'meshinfo': """
|
|
11
|
+
Display mesh information from FlowFM NetCDF files.
|
|
12
|
+
|
|
13
|
+
This tool reads a FlowFM NetCDF mesh file and reports the number of
|
|
14
|
+
nodes, faces, and edges, element type distribution (triangles vs
|
|
15
|
+
quadrilaterals), and the spatial extent of the mesh.
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
meshinfo -f FlowFM_net.nc # Display mesh info for a given file
|
|
19
|
+
meshinfo -f grid.nc # Any FlowFM mesh NetCDF file
|
|
20
|
+
""",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main():
|
|
25
|
+
parser = argparse.ArgumentParser(
|
|
26
|
+
prog='ncftools-info',
|
|
27
|
+
description='Display descriptions of ncftools commands',
|
|
28
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
'tool',
|
|
32
|
+
nargs='?',
|
|
33
|
+
choices=list(TOOL_DESCRIPTIONS.keys()),
|
|
34
|
+
help='Tool name to describe (omit to list all tools)',
|
|
35
|
+
)
|
|
36
|
+
args = parser.parse_args()
|
|
37
|
+
|
|
38
|
+
if args.tool:
|
|
39
|
+
print(f"\n--- {args.tool} ---")
|
|
40
|
+
print(dedent(TOOL_DESCRIPTIONS[args.tool]))
|
|
41
|
+
else:
|
|
42
|
+
print("\nNCFTOOLS — NetCDF utility commands\n")
|
|
43
|
+
for tool, desc in TOOL_DESCRIPTIONS.items():
|
|
44
|
+
first_line = dedent(desc).strip().splitlines()[0]
|
|
45
|
+
print(f" {tool:<14} {first_line}")
|
|
46
|
+
print("\nRun 'ncftools-info <tool>' for details on a specific command.")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
main()
|
ncftools/meshinfo.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
meshinfo - Display mesh information from FlowFM NetCDF files
|
|
4
|
+
Uses netCDF4 Python bindings
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
import netCDF4 as nc
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def show_mesh_info(nc_file):
|
|
16
|
+
"""
|
|
17
|
+
Display mesh information from a FlowFM NetCDF file.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
nc_file (str): Path to the FlowFM NetCDF mesh file
|
|
21
|
+
"""
|
|
22
|
+
dataset = nc.Dataset(nc_file, 'r')
|
|
23
|
+
|
|
24
|
+
print(f"FlowFM Mesh Information from: {nc_file}")
|
|
25
|
+
print("=" * 60)
|
|
26
|
+
|
|
27
|
+
nodes = dataset.dimensions['Mesh2d_nNodes'].size
|
|
28
|
+
faces = dataset.dimensions['Mesh2d_nFaces'].size
|
|
29
|
+
edges = dataset.dimensions['Mesh2d_nEdges'].size
|
|
30
|
+
|
|
31
|
+
print(f"Number of mesh nodes: {nodes:,}")
|
|
32
|
+
print(f"Number of mesh faces: {faces:,}")
|
|
33
|
+
print(f"Number of mesh edges: {edges:,}")
|
|
34
|
+
|
|
35
|
+
if 'Mesh2d_face_nodes' in dataset.variables:
|
|
36
|
+
face_nodes = dataset.variables['Mesh2d_face_nodes'][:]
|
|
37
|
+
fill_value = dataset.variables['Mesh2d_face_nodes']._FillValue
|
|
38
|
+
valid_nodes = np.sum(face_nodes != fill_value, axis=1)
|
|
39
|
+
|
|
40
|
+
triangles = int(np.sum(valid_nodes == 3))
|
|
41
|
+
quads = int(np.sum(valid_nodes == 4))
|
|
42
|
+
|
|
43
|
+
print("\nElement Types:")
|
|
44
|
+
print(f" Triangular elements: {triangles:,}")
|
|
45
|
+
print(f" Quadrilateral elements: {quads:,}")
|
|
46
|
+
print(f" Total elements: {triangles + quads:,}")
|
|
47
|
+
|
|
48
|
+
if 'Mesh2d_node_x' in dataset.variables and 'Mesh2d_node_y' in dataset.variables:
|
|
49
|
+
x_coords = dataset.variables['Mesh2d_node_x'][:]
|
|
50
|
+
y_coords = dataset.variables['Mesh2d_node_y'][:]
|
|
51
|
+
|
|
52
|
+
print("\nSpatial extent:")
|
|
53
|
+
print(f" X range: {np.min(x_coords):.1f} to {np.max(x_coords):.1f}")
|
|
54
|
+
print(f" Y range: {np.min(y_coords):.1f} to {np.max(y_coords):.1f}")
|
|
55
|
+
|
|
56
|
+
dataset.close()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def main():
|
|
60
|
+
parser = argparse.ArgumentParser(
|
|
61
|
+
prog='meshinfo',
|
|
62
|
+
description='Display mesh information from FlowFM NetCDF files',
|
|
63
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
64
|
+
epilog="""
|
|
65
|
+
Examples:
|
|
66
|
+
meshinfo -f FlowFM_net.nc # Specify a NetCDF mesh file
|
|
67
|
+
meshinfo -f grid.nc # Use any FlowFM mesh file
|
|
68
|
+
meshinfo -h # Show this help message
|
|
69
|
+
|
|
70
|
+
The tool displays:
|
|
71
|
+
- Number of nodes, faces, and edges
|
|
72
|
+
- Element type distribution (triangles vs quadrilaterals)
|
|
73
|
+
- Spatial extent (X and Y coordinate ranges)
|
|
74
|
+
""",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
'-f', '--file',
|
|
79
|
+
required=True,
|
|
80
|
+
metavar='FILE',
|
|
81
|
+
help='Path to the FlowFM NetCDF mesh file',
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
args = parser.parse_args()
|
|
85
|
+
|
|
86
|
+
if not os.path.isfile(args.file):
|
|
87
|
+
print(f"Error: File '{args.file}' not found.")
|
|
88
|
+
print(f"Current directory: {os.getcwd()}")
|
|
89
|
+
print("Please check the file path and try again.")
|
|
90
|
+
sys.exit(1)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
show_mesh_info(args.file)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
print(f"Error reading NetCDF file: {e}")
|
|
96
|
+
sys.exit(1)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ncftools
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A collection of tools for working with NetCDF files
|
|
5
|
+
Author-email: aaronchh <aaronhsu219@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AaronOET/ncftools
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: numpy>=1.20.0
|
|
13
|
+
Requires-Dist: netCDF4>=1.6.0
|
|
14
|
+
|
|
15
|
+
# NCFTOOLS
|
|
16
|
+
|
|
17
|
+
A collection of Python tools for working with NetCDF files.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install -e .
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- **meshinfo**: Display mesh information from FlowFM NetCDF files (node/face/edge counts, element types, spatial extent)
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Command-line
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# List all available commands
|
|
35
|
+
ncftools-info
|
|
36
|
+
|
|
37
|
+
# Display mesh information from a FlowFM NetCDF file
|
|
38
|
+
meshinfo -f FlowFM_net.nc
|
|
39
|
+
|
|
40
|
+
# Show help for meshinfo
|
|
41
|
+
meshinfo -h
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Python API
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from ncftools import meshinfo
|
|
48
|
+
|
|
49
|
+
# Display mesh info for a NetCDF file
|
|
50
|
+
meshinfo.show_mesh_info("FlowFM_net.nc")
|
|
51
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ncftools/__init__.py,sha256=A9QHKf1UA0ePNgIUariJsNhMUF3HGI2T-B7_BYw7RhU,207
|
|
2
|
+
ncftools/cli.py,sha256=N-LecSrDURy_uvQFh57upvoWRIYprhTrvAj07rw1gGQ,812
|
|
3
|
+
ncftools/describe.py,sha256=CW89EKkPq0jgTpoFuQxB6zlO46QM-x0nnsD6YYclfVM,1525
|
|
4
|
+
ncftools/meshinfo.py,sha256=rFDEJs2JPLvAITm8wjh1jz2_DSpFbVXHwS31aGykAfw,2971
|
|
5
|
+
ncftools/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
ncftools-0.1.0.dist-info/METADATA,sha256=lLEHjBTBk67Nt4x7CHEPUZ7xJpf4Tarwbj7StszNhGw,1060
|
|
7
|
+
ncftools-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
8
|
+
ncftools-0.1.0.dist-info/entry_points.txt,sha256=ATHDbWTGOKdeTtcHgUICDVutpypAzmvXoISCtshb8-M,120
|
|
9
|
+
ncftools-0.1.0.dist-info/top_level.txt,sha256=sQF2Q9jJGb5XXwiun5tmyk_5O3Rd0U4AGzSsdAMcyrc,9
|
|
10
|
+
ncftools-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ncftools
|