NCAR/esmlab

compute_time_var is broken

matt-long opened this issue · 3 comments

I am not able to invoke the compute_time_var method on a dataset.

files = ['/glade/scratch/mclong/archive/g.e21.G1850ECOIAF.T62_g17.002/ocn/hist/g.e21.G1850ECOIAF.T62_g17.002.pop.h.0001-01.nc']
ds = xr.open_dataset(files[0], decode_times=False, decode_coords=False)
esmlab.EsmlabAccessor.compute_time_var(ds, midpoint=True, year_offset=0)

Yields the following.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/glade/work/mclong/miniconda3/envs/dev/lib/python3.7/site-packages/xarray/core/common.py in __setattr__(self, name, value)
    186                 # to avoid key lookups with attribute-style access.
--> 187                 self.__getattribute__(name)
    188             except AttributeError:

AttributeError: 'Dataset' object has no attribute 'year_offset'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-11-f321accd20b7> in <module>
----> 1 esmlab.EsmlabAccessor.compute_time_var(ds, midpoint=True, year_offset=0)

/gpfs/u/home/mclong/codes/esmlab/esmlab/core.py in compute_time_var(self, midpoint, year_offset)
    123         The dataset with time coordinate modified.
    124         """
--> 125         self.year_offset = year_offset
    126         ds = self._ds_time_computed.copy(True)
    127         ds[self.time_coord_name] = self.get_time_decoded(midpoint)

/glade/work/mclong/miniconda3/envs/dev/lib/python3.7/site-packages/xarray/core/common.py in __setattr__(self, name, value)
    190                     "cannot set attribute %r on a %r object. Use __setitem__ "
    191                     "style assignment (e.g., `ds['name'] = ...`) instead to "
--> 192                     "assign variables." % (name, type(self).__name__))
    193         object.__setattr__(self, name, value)
    194 

AttributeError: cannot set attribute 'year_offset' on a 'Dataset' object. Use __setitem__ style assignment (e.g., `ds['name'] = ...`) instead to assign variables.

If I try this:

ds.esmlab.compute_time_var()

I get the following.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-20396bd7bb3d> in <module>
----> 1 ds.esmlab.compute_time_var()

/gpfs/u/home/mclong/codes/esmlab/esmlab/core.py in compute_time_var(self, midpoint, year_offset)
    124         """
    125         self.year_offset = year_offset
--> 126         ds = self._ds_time_computed.copy(True)
    127         ds[self.time_coord_name] = self.get_time_decoded(midpoint)
    128         return ds

AttributeError: 'NoneType' object has no attribute 'copy'

@matt-long, because xarray's accessors only accept one argument, which is an xarray.Dataset in this case, I added a somewhat unpleasant hack .esmlab.set_time() to allow passing attributes such as year_offset, time_coord_name to the class' instance.

In order to get compute_time_var to work, try this

ds.esmlab.set_time('time').compute_time_var()

or

ds.esmlab.set_time().compute_time_var()

In case we don't need to instantiate the accessor with year_offset, time_coord_name attributes, we can remove this hack. Let me know what you think.

That works, thanks. I will need to get to know this code better and perhaps we can discuss how to improve the interface. The original intent was to provide this as a utility for the user.