Skip to content

Commit 2bd353a

Browse files
committed
Add getter methods to hide techinical details for wrapping GMT_GRID/GMT_IMAGE
1 parent 3482568 commit 2bd353a

File tree

1 file changed

+100
-50
lines changed

1 file changed

+100
-50
lines changed

pygmt/datatypes/header.py

+100-50
Original file line numberDiff line numberDiff line change
@@ -143,42 +143,23 @@ class _GMT_GRID_HEADER(ctp.Structure): # noqa: N801
143143
("hidden", ctp.c_void_p),
144144
]
145145

146-
def _parse_header(self) -> tuple[tuple, dict, int, int]:
146+
def _parse_dimensions(self) -> dict[str, list]:
147147
"""
148-
Get dimension names, attributes, grid registration and type from the grid
149-
header.
148+
Get dimension names and attributes from the grid header.
150149
151-
For a 2-D grid, the dimension names are set to "y", "x", and "z" by default. The
150+
For a 2-D grid, the dimension names are set to "y" and "x" by default. The
152151
attributes for each dimension are parsed from the grid header following GMT
153152
source codes. See the GMT functions "gmtnc_put_units", "gmtnc_get_units" and
154153
"gmtnc_grd_info" for reference.
155154
156-
The last dimension is special and is the data variable name, and the attributes
157-
for this dimension are global attributes for the grid.
158-
159-
The grid is assumed to be Cartesian by default. If the x and y units are
160-
"degrees_east" and "degrees_north", respectively, then the grid is assumed to be
161-
geographic.
162-
163-
Parameters
164-
----------
165-
header
166-
The grid header structure.
167-
168155
Returns
169156
-------
170-
dims : tuple
171-
The dimension names, with the last dimension being the data variable.
172-
attrs : dict
173-
The attributes for each dimension.
174-
registration : int
175-
The grid registration. 0 for gridline and 1 for pixel.
176-
gtype : int
177-
The grid type. 0 for Cartesian grid and 1 for geographic grid.
157+
dict
158+
Dictionary containing the list of dimension names and attributes.
178159
"""
179-
# Default dimension names. The last dimension is for the data variable.
180-
dims: tuple = ("y", "x", "z")
181-
nameunits = (self.y_units, self.x_units, self.z_units)
160+
# Default dimension names.
161+
dims: tuple = ("y", "x")
162+
nameunits = (self.y_units, self.x_units)
182163

183164
# Dictionary for dimension attributes with the dimension name as the key.
184165
attrs: dict = {dim: {} for dim in dims}
@@ -203,26 +184,95 @@ def _parse_header(self) -> tuple[tuple, dict, int, int]:
203184
newdims[dim] = "lat"
204185

205186
# Axis attributes are "X"/"Y"/"Z"/"T" for horizontal/vertical/time axis.
206-
# The codes here may not work for 3-D grids.
207-
if dim == dims[-1]: # The last dimension is the data.
208-
attrs[dim]["actual_range"] = np.array([self.z_min, self.z_max])
209-
else:
210-
attrs[dim]["axis"] = dim.upper()
211-
idx = 2 if dim == "y" else 0
212-
attrs[dim]["actual_range"] = np.array(self.wesn[idx : idx + 2])
213-
214-
# Cartesian or Geographic grid
215-
gtype = 0
216-
if (
217-
attrs[dims[1]].get("standard_name") == "longitude"
218-
and attrs[dims[0]].get("standard_name") == "latitude"
219-
):
220-
gtype = 1
221-
# Registration
222-
registration = self.registration
223-
224-
# Update the attributes dictionary with new dimension names as keys
225-
attrs = {newdims[dim]: attrs[dim] for dim in dims}
226-
# Update the dimension names
227-
dims = tuple(newdims[dim] for dim in dims)
228-
return dims, attrs, registration, gtype
187+
attrs[dim]["axis"] = dim.upper()
188+
idx = 2 if dim == "y" else 0
189+
attrs[dim]["actual_range"] = np.array(self.wesn[idx : idx + 2])
190+
191+
# Save the lists of dimension names and attributes in the _nc attribute.
192+
self._nc = {
193+
"dims": [newdims[dim] for dim in dims],
194+
"attrs": [attrs[dim] for dim in dims],
195+
}
196+
197+
def get_name(self) -> str:
198+
"""
199+
Get the name of the grid from the grid header.
200+
201+
Returns
202+
-------
203+
name
204+
The name of the grid.
205+
"""
206+
return "z"
207+
208+
def get_data_attrs(self) -> dict:
209+
"""
210+
Get the attributes for the data variable from the grid header.
211+
212+
Returns
213+
-------
214+
attrs
215+
The attributes for the data variable.
216+
"""
217+
attrs = {}
218+
long_name, units = _parse_nameunits(self.z_units.decode())
219+
if long_name:
220+
attrs["long_name"] = long_name
221+
if units:
222+
attrs["units"] = units
223+
attrs["actual_range"] = np.array([self.z_min, self.z_max])
224+
return attrs
225+
226+
def get_dims(self):
227+
"""
228+
Get the dimension names from the grid header.
229+
230+
Returns
231+
-------
232+
dims : tuple
233+
The dimension names.
234+
"""
235+
if not hasattr(self, "_nc"):
236+
self._parse_dimensions()
237+
return self._nc["dims"]
238+
239+
def get_dim_attrs(self) -> list:
240+
"""
241+
Get the attributes for each dimension from the grid header.
242+
243+
Returns
244+
-------
245+
attrs
246+
List of attributes for each dimension.
247+
"""
248+
if not hasattr(self, "_nc"):
249+
self._parse_dimensions()
250+
return self._nc["attrs"]
251+
252+
def get_gtype(self) -> int:
253+
"""
254+
Get the grid type from the grid header.
255+
256+
The grid is assumed to be Cartesian by default. If the x/y dimensions are named
257+
"lon"/"lat" or have units "degrees_east"/"degrees_north", then the grid is
258+
assumed to be geographic.
259+
260+
Returns
261+
-------
262+
gtype
263+
The grid type. 0 for Cartesian grid and 1 for geographic grid.
264+
"""
265+
dims = self.get_dims()
266+
gtype = 1 if dims[0] == "lat" and dims[1] == "lon" else 0
267+
return gtype
268+
269+
def get_registration(self) -> int:
270+
"""
271+
Get the grid registration from the grid header.
272+
273+
Returns
274+
-------
275+
registration
276+
The grid registration. 0 for gridline and 1 for pixel.
277+
"""
278+
return self.registration

0 commit comments

Comments
 (0)