cf-python icon indicating copy to clipboard operation
cf-python copied to clipboard

Encounter error when reproducing recipe

Open Nemo1166 opened this issue 1 year ago • 3 comments

UFuncTypeError: Cannot cast ufunc 'subtract' output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

Expectation

Same with recipe 1 in documentation.

Reproduction

Run plot_01_recipe.ipynb, with data file cru_ts4.06.1901.2021.tmp.dat.nc (link).

Traceback info

here
{
	"name": "UFuncTypeError",
	"message": "Cannot cast ufunc 'subtract' output from dtype('float64') to dtype('int64') with casting rule 'same_kind'",
	"stack": "---------------------------------------------------------------------------
UFuncTypeError                            Traceback (most recent call last)
c:\\Users\\10502\\Desktop\\dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9\\plot_01_recipe.ipynb 单元格 22 line 1
----> <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=0'>1</a> annual_global_avg = global_avg.collapse(\"T: mean\", group=cf.Y())
      <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=1'>2</a> cfp.lineplot(
      <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=2'>3</a>     annual_global_avg,
      <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=3'>4</a>     color=\"red\",
      <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=4'>5</a>     title=\"Annual global mean surface temperature\",
      <a href='vscode-notebook-cell:/c%3A/Users/10502/Desktop/dataset-derived-near-surface-meteorological-variables-a2eeaa79-acc2-4c4a-9e90-b5b6ecd9c3f9/plot_01_recipe.ipynb#X30sZmlsZQ%3D%3D?line=5'>6</a> )

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\decorators.py:71, in _deprecated_kwarg_check.<locals>.deprecated_kwarg_check_decorator.<locals>.precede_with_kwarg_deprecation_check(self, *args, **kwargs)
     62         pass_in_kwarg = {depr_kwarg: True}
     63         _DEPRECATION_ERROR_KWARGS(
     64             self,
     65             operation_method.__name__,
   (...)
     68             removed_at=removed_at,
     69         )  # pragma: no cover
---> 71 operation_method_result = operation_method(self, *args, **kwargs)
     73 # Decorated method has same return signature as if undecorated:
     74 return operation_method_result

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cfdm\\decorators.py:171, in _manage_log_level_via_verbosity.<locals>.verbose_override_wrapper(*args, **kwargs)
    168 # After method completes, re-set any changes to log level or
    169 # enabling
    170 try:
--> 171     return method_with_verbose_kwarg(*args, **kwargs)
    172 except Exception:
    173     raise

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\field.py:7941, in Field.collapse(self, method, axes, squeeze, mtol, weights, ddof, a, inplace, group, regroup, within_days, within_years, over_days, over_years, coordinate, group_by, group_span, group_contiguous, measure, scale, radius, great_circle, verbose, remove_vertical_crs, _create_zero_size_cell_bounds, _update_cell_methods, i, _debug, **kwargs)
   7937         g_weights = None
   7939 axis = [a for a in collapse_axes][0]
-> 7941 f = f._collapse_grouped(
   7942     method,
   7943     axis,
   7944     within=within,
   7945     over=over,
   7946     within_days=within_days,
   7947     within_years=within_years,
   7948     over_days=over_days,
   7949     over_years=over_years,
   7950     group=group,
   7951     group_span=group_span,
   7952     group_contiguous=group_contiguous,
   7953     regroup=regroup,
   7954     mtol=mtol,
   7955     ddof=ddof,
   7956     measure=measure,
   7957     weights=g_weights,
   7958     squeeze=squeeze,
   7959     coordinate=coordinate,
   7960     group_by=group_by,
   7961     axis_in=axes_in[0],
   7962     verbose=verbose,
   7963 )
   7965 if regroup:
   7966     # Grouped collapse: Return the numpy array
   7967     return f

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cfdm\\decorators.py:171, in _manage_log_level_via_verbosity.<locals>.verbose_override_wrapper(*args, **kwargs)
    168 # After method completes, re-set any changes to log level or
    169 # enabling
    170 try:
--> 171     return method_with_verbose_kwarg(*args, **kwargs)
    172 except Exception:
    173     raise

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\field.py:8893, in Field._collapse_grouped(self, method, axis, within, over, within_days, within_years, over_days, over_years, group, group_span, group_contiguous, mtol, ddof, regroup, coordinate, measure, weights, squeeze, group_by, axis_in, verbose)
   8887 classification.fill(-1)
   8889 lower, upper, lower_limit, upper_limit = _tyu(
   8890     coord, group_by, True
   8891 )
-> 8893 classification, n = _time_interval(
   8894     classification,
   8895     0,
   8896     coord=coord,
   8897     interval=group,
   8898     lower=lower,
   8899     upper=upper,
   8900     lower_limit=lower_limit,
   8901     upper_limit=upper_limit,
   8902     group_by=group_by,
   8903 )
   8905 if group_span is True or group_span is None:
   8906     # Use the group definition as the group span
   8907     group_span = group

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\field.py:8397, in Field._collapse_grouped.<locals>._time_interval(classification, n, coord, interval, lower, upper, lower_limit, upper_limit, group_by, extra_condition)
   8395     while lower <= upper_limit:
   8396         lower, upper = interval.interval(lower)
-> 8397         classification, n, lower, upper = _ddddd(
   8398             classification,
   8399             n,
   8400             lower,
   8401             upper,
   8402             True,
   8403             coord,
   8404             group_by_coords,
   8405             extra_condition,
   8406         )
   8407 else:
   8408     # Decreasing dimension coordinate
   8409     lower, upper = interval.bounds(upper)

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\field.py:8336, in Field._collapse_grouped.<locals>._ddddd(classification, n, lower, upper, increasing, coord, group_by_coords, extra_condition)
   8333 if extra_condition:
   8334     q &= extra_condition
-> 8336 index = q.evaluate(coord).array
   8337 classification[index] = n
   8339 if increasing:

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\mixin\\propertiesdata.py:2437, in PropertiesData.array(self)
   2434 if data is None:
   2435     raise AttributeError(f\"{self.__class__.__name__} has no data\")
-> 2437 return data.array

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\data\\data.py:5096, in Data.array(self)
   5054 @property
   5055 def array(self):
   5056     \"\"\"A numpy array copy of the data.
   5057 
   5058     In-place changes to the returned numpy array do not affect the
   (...)
   5094 
   5095     \"\"\"
-> 5096     array = self.compute().copy()
   5097     if not isinstance(array, np.ndarray):
   5098         array = np.asanyarray(array)

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\data\\data.py:2652, in Data.compute(self)
   2620 def compute(self):  # noqa: F811
   2621     \"\"\"A numpy view the data.
   2622 
   2623     In-place changes to the returned numpy array *might* affect
   (...)
   2650 
   2651     \"\"\"
-> 2652     a = self.to_dask_array().compute()
   2654     if np.ma.isMA(a):
   2655         if self.hardmask:

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\dask\\base.py:342, in DaskMethodsMixin.compute(self, **kwargs)
    318 def compute(self, **kwargs):
    319     \"\"\"Compute this dask collection
    320 
    321     This turns a lazy Dask collection into its in-memory equivalent.
   (...)
    340     dask.compute
    341     \"\"\"
--> 342     (result,) = compute(self, traverse=False, **kwargs)
    343     return result

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\dask\\base.py:628, in compute(traverse, optimize_graph, scheduler, get, *args, **kwargs)
    625     postcomputes.append(x.__dask_postcompute__())
    627 with shorten_traceback():
--> 628     results = schedule(dsk, keys, **kwargs)
    630 return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\data\\dask_utils.py:643, in cf_units(a, from_units, to_units)
    606 def cf_units(a, from_units, to_units):
    607     \"\"\"Convert array values to have different equivalent units.
    608 
    609     .. versionadded:: 3.14.0
   (...)
    641 
    642     \"\"\"
--> 643     return Units.conform(
    644         a, from_units=from_units, to_units=to_units, inplace=False
    645     )

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cf\\units.py:29, in Units.conform(*args, **kwargs)
     27 @staticmethod
     28 def conform(*args, **kwargs):
---> 29     return cfUnits.conform(*args, **kwargs)

File c:\\Users\\10502\\miniforge3\\envs\\cf311\\Lib\\site-packages\\cfunits\\units.py:2297, in Units.conform(cls, x, from_units, to_units, inplace)
   2293         _cv_free(cv_converter)
   2295         offset *= scale.item()
-> 2297     x -= offset
   2299 return x

UFuncTypeError: Cannot cast ufunc 'subtract' output from dtype('float64') to dtype('int64') with casting rule 'same_kind'"
}

Env

# cf.environment(paths=False)
Platform: Windows-10-10.0.22631-SP0
HDF5 library: 1.14.2
netcdf library: 4.9.2
udunits2 library: C:\Users\10502\miniforge3\envs\cf311\Scripts\udunits2.dll
esmpy/ESMF: 8.4.2
Python: 3.11.6
dask: 2023.11.0
netCDF4: 1.6.5
psutil: 5.9.5
packaging: 23.2
numpy: 1.26.2
scipy: 1.11.4
matplotlib: 3.8.2
cftime: 1.6.3
cfunits: 3.3.6
cfplot: 3.2.23
cfdm: 1.10.1.2
cf: 3.15.4

Nemo1166 avatar Nov 30 '23 19:11 Nemo1166

error also occurred when reproducing this in Docs:Analysis.

Nemo1166 avatar Dec 01 '23 14:12 Nemo1166

It seems can be solved by following modification:

In pkg cfunits, file units.py, line 2297:

-  x -= offset
+  x = x - offset

I haven't check other components to avoid potential problems.

Nemo1166 avatar Dec 01 '23 15:12 Nemo1166

Thanks for reporting this! We'll look into it soon. I'll comment here with any updates from when we get a chance to work on it.

sadielbartholomew avatar Dec 06 '23 01:12 sadielbartholomew