77from uxarray .io ._ugrid import _is_ugrid , _read_ugrid
88
99
10+ def _is_exodus (dataset : xr .Dataset ) -> bool :
11+ """Check whether a dataset looks like an Exodus mesh."""
12+ has_packed_coords = "coord" in dataset
13+ has_split_coords = {"coordx" , "coordy" }.issubset (dataset .variables )
14+ has_connectivity = any (
15+ name .startswith ("connect" ) for name in dataset .variables
16+ ) or any ("num_nod_per_el" in dim for dim in dataset .dims )
17+
18+ return has_connectivity and (has_packed_coords or has_split_coords )
19+
20+
21+ def _is_scrip (dataset : xr .Dataset ) -> bool :
22+ """Check whether a dataset looks like an unstructured SCRIP grid."""
23+ required_vars = {
24+ "grid_center_lon" ,
25+ "grid_center_lat" ,
26+ "grid_corner_lon" ,
27+ "grid_corner_lat" ,
28+ }
29+ unstructured_markers = {"grid_imask" , "grid_rank" , "grid_area" }
30+
31+ return required_vars .issubset (dataset .variables ) and any (
32+ marker in dataset for marker in unstructured_markers
33+ )
34+
35+
36+ def _is_mpas (dataset : xr .Dataset ) -> bool :
37+ """Check whether a dataset looks like an MPAS grid."""
38+ if "verticesOnCell" not in dataset :
39+ return False
40+
41+ companion_groups = (
42+ {"nEdgesOnCell" },
43+ {"latCell" , "lonCell" },
44+ {"latVertex" , "lonVertex" },
45+ {"xCell" , "yCell" , "zCell" },
46+ {"xVertex" , "yVertex" , "zVertex" },
47+ )
48+
49+ return any (group .issubset (dataset .variables ) for group in companion_groups )
50+
51+
52+ def _is_esmf (dataset : xr .Dataset ) -> bool :
53+ """Check whether a dataset looks like an ESMF mesh."""
54+ return "maxNodePElement" in dataset .dims and "elementConn" in dataset
55+
56+
57+ def _is_geos_cs (dataset : xr .Dataset ) -> bool :
58+ """Check whether a dataset looks like a GEOS cube-sphere grid."""
59+ required_dims = {"nf" , "YCdim" , "XCdim" }
60+ required_vars = {"corner_lons" , "corner_lats" }
61+
62+ return required_dims .issubset (dataset .sizes ) and required_vars .issubset (
63+ dataset .variables
64+ )
65+
66+
67+ def _is_icon (dataset : xr .Dataset ) -> bool :
68+ """Check whether a dataset looks like an ICON grid."""
69+ required_vars = {"vertex_of_cell" , "clon" , "clat" , "vlon" , "vlat" }
70+ return required_vars .issubset (dataset .variables )
71+
72+
73+ def _is_fesom2 (dataset : xr .Dataset ) -> bool :
74+ """Check whether a dataset looks like a FESOM2 grid."""
75+ return "triag_nodes" in dataset
76+
77+
1078def _parse_grid_type (dataset ):
1179 """Checks input and contents to determine grid type. Supports detection of
1280 UGrid, SCRIP, Exodus, ESMF, and shape file.
@@ -31,27 +99,21 @@ def _parse_grid_type(dataset):
3199
32100 _structured , lon_name , lat_name = _is_structured (dataset )
33101
34- if "coord" in dataset :
35- # exodus with coord or coordx
36- mesh_type = "Exodus"
37- elif "coordx" in dataset :
102+ if _is_exodus (dataset ):
38103 mesh_type = "Exodus"
39- elif "grid_center_lon" in dataset :
40- # scrip with grid_center_lon
104+ elif _is_scrip (dataset ):
41105 mesh_type = "Scrip"
42106 elif _is_ugrid (dataset ):
43- # ugrid topology is present
44107 mesh_type = "UGRID"
45- elif "verticesOnCell" in dataset :
108+ elif _is_mpas ( dataset ) :
46109 mesh_type = "MPAS"
47- elif "maxNodePElement" in dataset . dims :
110+ elif _is_esmf ( dataset ) :
48111 mesh_type = "ESMF"
49- elif all (key in dataset .sizes for key in ["nf" , "YCdim" , "XCdim" ]):
50- # expected dimensions for a GEOS cube sphere grid
112+ elif _is_geos_cs (dataset ):
51113 mesh_type = "GEOS-CS"
52- elif "vertex_of_cell" in dataset :
114+ elif _is_icon ( dataset ) :
53115 mesh_type = "ICON"
54- elif "triag_nodes" in dataset :
116+ elif _is_fesom2 ( dataset ) :
55117 mesh_type = "FESOM2"
56118 elif _structured :
57119 mesh_type = "Structured"
0 commit comments