Skip to content

Commit 89fc0a1

Browse files
committed
Add dataset comparison tooling
And remove redundant docstring
1 parent 7e63404 commit 89fc0a1

2 files changed

Lines changed: 92 additions & 2 deletions

File tree

parcels/_datasets/structured/generic.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"""Datasets focussing on grid geometry"""
2-
31
import numpy as np
42
import xarray as xr
53

parcels/_datasets/utils.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,95 @@ def dataset_repr_diff(ds1: xr.Dataset, ds2: xr.Dataset) -> str:
6565

6666
diff = difflib.ndiff(repr1.splitlines(keepends=True), repr2.splitlines(keepends=True))
6767
return "".join(diff)
68+
69+
70+
def compare_datasets(ds1, ds2, ds1_name="Dataset 1", ds2_name="Dataset 2"):
71+
print(f"Comparing {ds1_name} and {ds2_name}\n")
72+
73+
# Compare dataset attributes
74+
print("Dataset Attributes Comparison:")
75+
if ds1.attrs == ds2.attrs:
76+
print(" Dataset attributes are identical.")
77+
else:
78+
print(" Dataset attributes differ.")
79+
for attr_name in set(ds1.attrs.keys()) | set(ds2.attrs.keys()):
80+
if attr_name not in ds1.attrs:
81+
print(f" Attribute '{attr_name}' only in {ds2_name}")
82+
elif attr_name not in ds2.attrs:
83+
print(f" Attribute '{attr_name}' only in {ds1_name}")
84+
elif ds1.attrs[attr_name] != ds2.attrs[attr_name]:
85+
print(f" Attribute '{attr_name}' differs:")
86+
print(f" {ds1_name}: {ds1.attrs[attr_name]}")
87+
print(f" {ds2_name}: {ds2.attrs[attr_name]}")
88+
print("-" * 30)
89+
90+
# Compare dimensions
91+
print("Dimensions Comparison:")
92+
ds1_dims = set(ds1.dims)
93+
ds2_dims = set(ds2.dims)
94+
if ds1_dims == ds2_dims:
95+
print(" Dimension names are identical.")
96+
else:
97+
print(" Dimension names differ:")
98+
print(f" {ds1_name} dims: {sorted(list(ds1_dims))}")
99+
print(f" {ds2_name} dims: {sorted(list(ds2_dims))}")
100+
101+
# For common dimensions, compare order (implicit by comparing coordinate values for sortedness)
102+
# and size (though size is parameterized and expected to be different)
103+
for dim_name in ds1_dims.intersection(ds2_dims):
104+
print(f" Dimension '{dim_name}':")
105+
# Sizes will differ due to DIM_SIZE, so we don't strictly compare them.
106+
print(f" {ds1_name} size: {ds1.dims[dim_name]}, {ds2_name} size: {ds2.dims[dim_name]}")
107+
# Check if coordinates associated with dimensions are sorted (increasing)
108+
if dim_name in ds1.coords and dim_name in ds2.coords:
109+
is_ds1_sorted = np.all(np.diff(ds1[dim_name].values) >= 0) if len(ds1[dim_name].values) > 1 else True
110+
is_ds2_sorted = np.all(np.diff(ds2[dim_name].values) >= 0) if len(ds2[dim_name].values) > 1 else True
111+
if is_ds1_sorted == is_ds2_sorted:
112+
print(f" Order for '{dim_name}' is consistent (both sorted: {is_ds1_sorted})")
113+
else:
114+
print(
115+
f" Order for '{dim_name}' differs: {ds1_name} sorted: {is_ds1_sorted}, {ds2_name} sorted: {is_ds2_sorted}"
116+
)
117+
print("-" * 30)
118+
119+
# Compare variables (name, attributes, dimensions used)
120+
print("Variables Comparison:")
121+
ds1_vars = set(ds1.variables.keys())
122+
ds2_vars = set(ds2.variables.keys())
123+
124+
if ds1_vars == ds2_vars:
125+
print(" Variable names are identical.")
126+
else:
127+
print(" Variable names differ:")
128+
print(f" {ds1_name} vars: {sorted(list(ds1_vars - ds2_vars))}")
129+
print(f" {ds2_name} vars: {sorted(list(ds2_vars - ds1_vars))}")
130+
print(f" Common vars: {sorted(list(ds1_vars.intersection(ds2_vars)))}")
131+
132+
for var_name in ds1_vars.intersection(ds2_vars):
133+
print(f" Variable '{var_name}':")
134+
var1 = ds1[var_name]
135+
var2 = ds2[var_name]
136+
137+
# Compare attributes
138+
if var1.attrs == var2.attrs:
139+
print(" Attributes are identical.")
140+
else:
141+
print(" Attributes differ.")
142+
for attr_name in set(var1.attrs.keys()) | set(var2.attrs.keys()):
143+
if attr_name not in var1.attrs:
144+
print(f" Attribute '{attr_name}' only in {ds2_name}'s '{var_name}'")
145+
elif attr_name not in var2.attrs:
146+
print(f" Attribute '{attr_name}' only in {ds1_name}'s '{var_name}'")
147+
elif var1.attrs[attr_name] != var2.attrs[attr_name]:
148+
print(f" Attribute '{attr_name}' differs for '{var_name}':")
149+
print(f" {ds1_name}: {var1.attrs[attr_name]}")
150+
print(f" {ds2_name}: {var2.attrs[attr_name]}")
151+
152+
# Compare dimensions used by the variable
153+
if var1.dims == var2.dims:
154+
print(f" Dimensions used are identical: {var1.dims}")
155+
else:
156+
print(" Dimensions used differ:")
157+
print(f" {ds1_name}: {var1.dims}")
158+
print(f" {ds2_name}: {var2.dims}")
159+
print("=" * 30 + " End of Comparison " + "=" * 30)

0 commit comments

Comments
 (0)