Skip to content

Commit 82fc6a3

Browse files
authored
Fixing behavior of dimensions of size 1 (#289)
* Forgot to squeeze strings in cdfread * Adding a check for label dimensions which should have been in there all along
1 parent 12288f8 commit 82fc6a3

3 files changed

Lines changed: 38 additions & 30 deletions

File tree

cdflib/cdfread.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,9 +1699,14 @@ def _read_data(
16991699
onerec.append(string1)
17001700
strings.extend(onerec)
17011701
ret = np.array(strings).reshape((num_recs,) + tuple(dimensions))
1702+
if squeeze_needed:
1703+
ret = np.squeeze(ret, axis=(ret.ndim - 1))
1704+
if dimensions is not None:
1705+
dimensions.pop()
17021706
if self._majority == "Column_major":
17031707
axes = [0] + list(range(len(dimensions), 0, -1))
17041708
ret = np.transpose(ret, axes=axes)
1709+
17051710
return ret
17061711
else:
17071712
if (data_type == 1) or (data_type == 41):

cdflib/xarray/cdf_to_xarray.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,47 @@ def _convert_cdf_time_types(
3838
# Converts CDF time types into either datetime objects, unixtime, or nothing
3939
# If nothing, ALL CDF_EPOCH16 types are converted to CDF_EPOCH, because xarray can't handle int64s
4040
"""
41-
42-
data = np.atleast_1d(np.squeeze(data))
43-
41+
data = np.atleast_1d(data)
4442
# Convert all data in the "data" variable to unixtime or datetime if needed
4543
data_type = properties.Data_Type_Description
4644
if len(data) == 0 or data_type not in ("CDF_EPOCH", "CDF_EPOCH16", "CDF_TIME_TT2000"):
4745
new_data = data
4846
else:
47+
data = np.atleast_1d(np.squeeze(data))
4948
if to_datetime:
50-
new_data = cdfepoch.to_datetime(data)
49+
new_data = np.atleast_1d(cdfepoch.to_datetime(data))
5150
if "UNITS" in atts:
5251
atts["UNITS"].Data = "Datetime (UTC)"
5352
elif to_unixtime:
54-
new_data = cdfepoch.unixtime(data)
53+
new_data = np.atleast_1d(cdfepoch.unixtime(data))
5554
if "UNITS" in atts:
5655
atts["UNITS"].Data = "seconds"
5756
else:
5857
if data_type == "CDF_EPOCH16":
59-
new_data = cdfepoch.compute(cdfepoch.breakdown(data)[0:7])
58+
new_data = np.atleast_1d(cdfepoch.compute(cdfepoch.breakdown(data)[0:7]))
6059
else:
6160
new_data = data
6261

6362
# Convert all the attributes in the "atts" dictionary to unixtime or datetime if needed
64-
new_atts = {}
63+
new_atts: Dict[str, Any] = {}
6564
time_converted_attrs = []
6665
for att in atts:
6766
attr_data_type = atts[att].Data_Type
68-
data = atts[att].Data
67+
attr_data = atts[att].Data
6968
if attr_data_type not in ("CDF_EPOCH", "CDF_EPOCH16", "CDF_TIME_TT2000"):
70-
new_atts[att] = data
69+
new_atts[att] = attr_data
7170
else:
7271
if to_datetime:
7372
time_converted_attrs.append(att)
74-
new_atts[att] = cdfepoch.to_datetime(data)
73+
new_atts[att] = cdfepoch.to_datetime(np.array(attr_data))
7574
elif to_unixtime:
7675
time_converted_attrs.append(att)
77-
new_atts[att] = cdfepoch.unixtime(data)
76+
new_atts[att] = cdfepoch.unixtime(np.array(attr_data))
7877
else:
7978
if attr_data_type == "CDF_EPOCH16":
80-
new_atts[att] = cdfepoch.compute(cdfepoch.breakdown(data)[0:7])
79+
new_atts[att] = cdfepoch.compute(cdfepoch.breakdown(np.array(attr_data))[0:7])
8180
else:
82-
new_atts[att] = data
81+
new_atts[att] = attr_data
8382

8483
# This is a bit of a hack, these data types are ambiguous
8584
# Lets add an attribute so at least we retain some information about what these numbers represent
@@ -792,7 +791,7 @@ def cdf_to_xarray(filename: str, to_datetime: bool = True, to_unixtime: bool = F
792791
created_coord_vars[var_name] = created_vars[var_name]
793792
# Check if these coordinate variable have associated labels
794793
for lab in label_variables:
795-
if label_variables[lab] == var_name: # Found one!
794+
if label_variables[lab] == var_name: # Found one! Label "lab" covers the dimension "var_name"
796795
if len(created_vars[lab].dims) == len(created_vars[var_name].dims):
797796
if created_vars[lab].size != created_vars[var_name].size:
798797
logger.warning(
@@ -801,7 +800,12 @@ def cdf_to_xarray(filename: str, to_datetime: bool = True, to_unixtime: bool = F
801800
else:
802801
created_vars[lab].dims = created_vars[var_name].dims
803802
else:
804-
created_vars[lab].dims = (created_vars[var_name].dims[-1],)
803+
if created_vars[lab].shape[0] != created_vars[var_name].shape[-1]:
804+
logger.warning(
805+
f"Warning, label variable {lab} does not match the expected dimension sizes of {var_name}"
806+
)
807+
else:
808+
created_vars[lab].dims = (created_vars[var_name].dims[-1],)
805809
# Add the labels to the coordinates as well
806810
created_coord_vars[lab] = created_vars[lab]
807811
elif var_name in uncertainty_variables:

cdflib/xarray/xarray_to_cdf.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -317,21 +317,20 @@ def _verify_depend_dimensions(
317317

318318
# Check that the size of the dimension that DEPEND_{i} is refering to is
319319
# also the same size of the DEPEND_{i}'s last dimension
320-
for key in dataset[primary_variable_name].attrs:
321-
if key.lower() == "depend_0":
322-
if primary_data.shape[dimension_number] != coordinate_data.shape[-1]:
323-
_warn_or_except(
324-
f"ISTP Compliance Warning: {coordinate_variable_name} is listed as the DEPEND_{dimension_number} for variable {primary_variable_name}, but the dimensions do not match.",
325-
terminate_on_warning,
326-
)
327-
return False
328-
else:
329-
if primary_data.shape[dimension_number - 1] != coordinate_data.shape[-1]:
330-
_warn_or_except(
331-
f"ISTP Compliance Warning: {coordinate_variable_name} is listed as the DEPEND_{dimension_number} for variable {primary_variable_name}, but the dimensions do not match.",
332-
terminate_on_warning,
333-
)
334-
return False
320+
if any(k.lower() == "depend_0" for k in dataset[primary_variable_name].attrs):
321+
if primary_data.shape[dimension_number] != coordinate_data.shape[-1]:
322+
_warn_or_except(
323+
f"ISTP Compliance Warning: {coordinate_variable_name} is listed as the DEPEND_{dimension_number} for variable {primary_variable_name}, but the dimensions do not match.",
324+
terminate_on_warning,
325+
)
326+
return False
327+
else:
328+
if primary_data.shape[dimension_number - 1] != coordinate_data.shape[-1]:
329+
_warn_or_except(
330+
f"ISTP Compliance Warning: {coordinate_variable_name} is listed as the DEPEND_{dimension_number} for variable {primary_variable_name}, but the dimensions do not match.",
331+
terminate_on_warning,
332+
)
333+
return False
335334
except ISTPError as istp_e:
336335
raise istp_e
337336
except Exception as e:

0 commit comments

Comments
 (0)