Skip to content

Commit 1ddb9ec

Browse files
authored
Rename plot_transect with plot_cross_section (#65)
* Rename plot_transect with plot_cross_section * Define cross_section object and redefine transect * Fix cross-section issues
1 parent 8ddf655 commit 1ddb9ec

24 files changed

+527
-381
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repos:
1212
- id: check-ast
1313
- id: check-added-large-files
1414
- repo: https://github.com/astral-sh/ruff-pre-commit
15-
rev: v0.5.7
15+
rev: v0.6.2
1616
hooks:
1717
- id: ruff
1818
args: [--fix]

gpm/accessor/methods.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,32 @@ def collocate(
239239
decode_cf=decode_cf,
240240
)
241241

242-
#### Transect utility
242+
#### Transect/Trajectory utility
243+
244+
@auto_wrap_docstring
245+
def extract_at_points(
246+
self,
247+
points,
248+
method="nearest",
249+
new_dim="points",
250+
):
251+
from gpm.utils.manipulations import extract_at_points
252+
253+
return extract_at_points(
254+
self._obj,
255+
points=points,
256+
method=method,
257+
new_dim=new_dim,
258+
)
259+
243260
@auto_wrap_docstring
244261
def extract_transect_between_points(
245262
self,
246263
start_point,
247264
end_point,
248265
steps=100,
249266
method="linear",
267+
new_dim="transect",
250268
):
251269
from gpm.utils.manipulations import extract_transect_between_points
252270

@@ -256,6 +274,7 @@ def extract_transect_between_points(
256274
end_point=end_point,
257275
steps=steps,
258276
method=method,
277+
new_dim=new_dim,
259278
)
260279

261280
@auto_wrap_docstring
@@ -266,6 +285,7 @@ def extract_transect_around_point(
266285
distance,
267286
steps=100,
268287
method="linear",
288+
new_dim="transect",
269289
):
270290
from gpm.utils.manipulations import extract_transect_around_point
271291

@@ -276,20 +296,23 @@ def extract_transect_around_point(
276296
distance=distance,
277297
steps=steps,
278298
method=method,
299+
new_dim=new_dim,
279300
)
280301

281302
@auto_wrap_docstring
282-
def extract_transect_along_trajectory(
303+
def extract_transect_at_points(
283304
self,
284305
points,
285306
method="linear",
307+
new_dim="transect",
286308
):
287-
from gpm.utils.manipulations import extract_transect_along_trajectory
309+
from gpm.utils.manipulations import extract_transect_at_points
288310

289-
return extract_transect_along_trajectory(
311+
return extract_transect_at_points(
290312
self._obj,
291313
points=points,
292314
method=method,
315+
new_dim=new_dim,
293316
)
294317

295318
#### Range subset utility
@@ -841,7 +864,7 @@ def plot_image(
841864
)
842865

843866
@auto_wrap_docstring
844-
def plot_transect(
867+
def plot_cross_section(
845868
self,
846869
variable,
847870
ax=None,
@@ -854,9 +877,9 @@ def plot_transect(
854877
cbar_kwargs=None,
855878
**plot_kwargs,
856879
):
857-
from gpm.visualization.cross_section import plot_transect
880+
from gpm.visualization.cross_section import plot_cross_section
858881

859-
return plot_transect(
882+
return plot_cross_section(
860883
self._obj[variable],
861884
ax=ax,
862885
x=x,
@@ -1053,7 +1076,7 @@ def plot_image(
10531076
)
10541077

10551078
@auto_wrap_docstring
1056-
def plot_transect(
1079+
def plot_cross_section(
10571080
self,
10581081
ax=None,
10591082
x=None,
@@ -1065,9 +1088,9 @@ def plot_transect(
10651088
cbar_kwargs=None,
10661089
**plot_kwargs,
10671090
):
1068-
from gpm.visualization.cross_section import plot_transect
1091+
from gpm.visualization.cross_section import plot_cross_section
10691092

1070-
return plot_transect(
1093+
return plot_cross_section(
10711094
self._obj,
10721095
ax=ax,
10731096
x=x,

gpm/checks.py

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,20 @@ def get_frequency_dimension(xr_obj):
6969

7070
def get_vertical_dimension(xr_obj):
7171
"""Return the name of the available vertical dimension."""
72-
return np.array(VERTICAL_DIMS)[np.isin(VERTICAL_DIMS, list(xr_obj.dims))].tolist()
72+
vertical_dim = np.array(VERTICAL_DIMS)[np.isin(VERTICAL_DIMS, list(xr_obj.dims))].tolist()
73+
if len(vertical_dim) > 1:
74+
raise ValueError(f"Only one vertical dimension is allowed. Got {vertical_dim}.")
75+
return vertical_dim
7376

7477

7578
def get_spatial_dimensions(xr_obj):
7679
"""Return the name of the available spatial dimensions."""
7780
dims = list(xr_obj.dims)
7881
flattened_spatial_dims = list(chain.from_iterable(SPATIAL_DIMS))
79-
return np.array(flattened_spatial_dims)[np.isin(flattened_spatial_dims, dims)].tolist()
82+
spatial_dimensions = np.array(flattened_spatial_dims)[np.isin(flattened_spatial_dims, dims)].tolist()
83+
if len(spatial_dimensions) > 2:
84+
raise ValueError(f"Only two horizontal spatial dimensions are allowed. Got {spatial_dimensions}.")
85+
return spatial_dimensions
8086

8187

8288
def _has_spatial_dim_dataarray(da, strict):
@@ -230,9 +236,8 @@ def _is_expected_spatial_dims(spatial_dims):
230236
def is_orbit(xr_obj):
231237
"""Check whether the xarray object is a GPM ORBIT.
232238
233-
An ORBIT transect or nadir view is considered ORBIT.
234-
An ORBIT object must have the coordinates available !
235-
239+
An ORBIT cross-section (nadir view) or transect is considered ORBIT.
240+
An ORBIT object must have the coordinates available.
236241
"""
237242
from gpm.dataset.crs import _get_swath_dim_coords
238243

@@ -304,8 +309,8 @@ def _is_spatial_3d_dataarray(da, strict):
304309
return True
305310

306311

307-
def _is_transect_dataarray(da, strict):
308-
"""Check if the xarray.DataArray is a spatial 3D array."""
312+
def _is_cross_section_dataarray(da, strict):
313+
"""Check if the xarray.DataArray is a cross-section array."""
309314
spatial_dims = list(get_spatial_dimensions(da))
310315
if len(spatial_dims) != 1:
311316
return False
@@ -320,6 +325,16 @@ def _is_transect_dataarray(da, strict):
320325
return True
321326

322327

328+
def _is_transect_dataarray(da, strict):
329+
"""Check if the xarray.DataArray is a transect array."""
330+
spatial_dims = list(get_spatial_dimensions(da))
331+
if len(spatial_dims) != 1:
332+
return False
333+
if strict and len(da.dims) != 1: # noqa
334+
return False
335+
return True
336+
337+
323338
def _check_dataarrays_condition(condition, ds, strict):
324339
if not ds: # Empty dataset (no variables)
325340
return False
@@ -339,8 +354,13 @@ def _is_spatial_3d_dataset(ds, strict):
339354
return _check_dataarrays_condition(_is_spatial_3d_dataarray, ds=ds, strict=strict)
340355

341356

357+
def _is_cross_section_dataset(ds, strict):
358+
"""Check if all xarray.DataArrays of a xarray.Dataset are cross-section objects."""
359+
return _check_dataarrays_condition(_is_cross_section_dataarray, ds=ds, strict=strict)
360+
361+
342362
def _is_transect_dataset(ds, strict):
343-
"""Check if all xarray.DataArrays of a xarray.Dataset are transect objects."""
363+
"""Check if all xarray.DataArrays of a xarray.Dataset are transects objects."""
344364
return _check_dataarrays_condition(_is_transect_dataarray, ds=ds, strict=strict)
345365

346366

@@ -376,13 +396,31 @@ def is_spatial_3d(xr_obj, strict=True, squeeze=True):
376396
)
377397

378398

379-
def is_transect(xr_obj, strict=True, squeeze=True):
380-
"""Check if the xarray.DataArray or xarray.Dataset is a transect object.
399+
def is_cross_section(xr_obj, strict=True, squeeze=True):
400+
"""Check if the xarray.DataArray or xarray.Dataset is a cross-section object.
381401
382402
If ``squeeze=True`` (default), dimensions of size=1 are removed prior testing.
383403
If ``strict=True`` (default), the xarray.DataArray must have just the
384404
vertical dimension and a horizontal dimension.
385-
If ``strict=False`` , the xarray.DataArray can also have additional dimensions.
405+
If ``strict=False`` , the xarray.DataArray can have additional dimensions but only
406+
a single horizontal and vertical dimension.
407+
"""
408+
return _check_xarray_conditions(
409+
_is_cross_section_dataarray,
410+
_is_cross_section_dataset,
411+
xr_obj=xr_obj,
412+
strict=strict,
413+
squeeze=squeeze,
414+
)
415+
416+
417+
def is_transect(xr_obj, strict=True, squeeze=True):
418+
"""Check if the xarray.DataArray or xarray.Dataset is a transect object.
419+
420+
If ``squeeze=True`` (default), dimensions of size=1 are removed prior testing.
421+
If ``strict=True`` (default), the xarray.DataArray must have just an horizontal dimension.
422+
If ``strict=False`` , the xarray.DataArray can have additional dimensions but only a single
423+
horizontal dimension.
386424
"""
387425
return _check_xarray_conditions(
388426
_is_transect_dataarray,
@@ -449,16 +487,29 @@ def check_is_spatial_3d(xr_obj, strict=True, squeeze=True):
449487
raise ValueError("Expecting a 3D GPM field.")
450488

451489

452-
def check_is_transect(xr_obj, strict=True, squeeze=True):
453-
"""Check if the xarray.DataArray or xarray.Dataset is a transect.
490+
def check_is_cross_section(xr_obj, strict=True, squeeze=True):
491+
"""Check if the xarray.DataArray or xarray.Dataset is a cross-section.
454492
455493
If ``squeeze=True`` (default), dimensions of size=1 are removed prior testing.
456494
If ``strict=True`` (default), the xarray.DataArray must have just the
457495
vertical dimension and a horizontal dimension.
458-
If ``strict=False`` , the xarray.DataArray can also have additional dimensions.
496+
If ``strict=False`` , the xarray.DataArray can also have additional dimensions,
497+
but only a single vertical and horizontal dimension.
498+
"""
499+
if not is_cross_section(xr_obj, strict=strict, squeeze=squeeze):
500+
raise ValueError("Expecting a cross-section extracted from a 3D GPM field.")
501+
502+
503+
def check_is_transect(xr_obj, strict=True, squeeze=True):
504+
"""Check if the xarray.DataArray or xarray.Dataset is a transect.
505+
506+
If ``squeeze=True`` (default), dimensions of size=1 are removed prior testing.
507+
If ``strict=True`` (default), the xarray.DataArray must have just an horizontal dimension.
508+
If ``strict=False`` , the xarray.DataArray can also have additional dimensions,
509+
but only an horizontal dimension.
459510
"""
460511
if not is_transect(xr_obj, strict=strict, squeeze=squeeze):
461-
raise ValueError("Expecting a transect of a 3D GPM field.")
512+
raise ValueError("Expecting a transect object.")
462513

463514

464515
def check_has_vertical_dim(xr_obj, strict=False, squeeze=True):
@@ -523,16 +574,26 @@ def get_spatial_3d_variables(ds, strict=False, squeeze=True):
523574
return sorted(variables)
524575

525576

526-
def get_transect_variables(ds, strict=False, squeeze=True):
527-
"""Get list of xarray.Dataset trasect variables.
577+
def get_cross_section_variables(ds, strict=False, squeeze=True):
578+
"""Get list of xarray.Dataset cross-section variables.
528579
529-
If ``strict=False`` (default), the potential variables for which a transect can be derived.
530-
If ``strict=True``, the variables that are already provide a transect.
580+
If ``strict=False`` (default), the potential variables for which a strict cross-section can be derived.
581+
If ``strict=True``, the variables that are already a cross-section.
531582
"""
532-
variables = [var for var in get_dataset_variables(ds) if is_transect(ds[var], strict=strict, squeeze=squeeze)]
583+
variables = [var for var in get_dataset_variables(ds) if is_cross_section(ds[var], strict=strict, squeeze=squeeze)]
533584
return sorted(variables)
534585

535586

587+
# def get_transect_variables(ds, strict=False, squeeze=True):
588+
# """Get list of xarray.Dataset transect variables.
589+
590+
# If ``strict=False`` (default), the potential variables for which a strict transect can be derived.
591+
# If ``strict=True``, the variables that are already a transect.
592+
# """
593+
# variables = [var for var in get_dataset_variables(ds) if is_transect(ds[var], strict=strict, squeeze=squeeze)]
594+
# return sorted(variables)
595+
596+
536597
def get_vertical_variables(ds):
537598
"""Get list of xarray.Dataset variables with vertical dimension."""
538599
variables = [var for var in get_dataset_variables(ds) if has_vertical_dim(ds[var], strict=False, squeeze=True)]

gpm/dataset/dimensions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,12 @@
9090
}
9191

9292
SPATIAL_DIMS = [
93-
["transect"],
9493
["along_track", "cross_track"],
9594
["lat", "lon"],
9695
["latitude", "longitude"],
9796
["x", "y"], # compatibility with satpy/gpm_geo i.e.
97+
["transect"],
98+
["trajectory"],
9899
["beam"], # when stacking 2D spatial dims
99100
["pixel"], # when stacking 2D spatial dims
100101
]

gpm/io/download.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ def run(commands, n_threads=10, progress_bar=True, verbose=True):
264264
"""
265265
from tqdm import tqdm
266266

267-
if n_threads < 1:
268-
n_threads = 1
267+
n_threads = max(n_threads, 1)
269268
n_threads = min(n_threads, 10)
270269
n_cmds = len(commands)
271270

0 commit comments

Comments
 (0)