Project

General

Profile

Using Xarray as input with Python CDO wrapper

Added by Pauline Millet over 1 year ago

Hello,
I'm wondering if there is a way to use Xarray as input in CDO command?

As an example, let's say I select some years in a given netcdf file, a Xarray is returned. Then some processings are applied on it, and finally I want to compute a yearsum on that data (still in Xarray format):

my_xarray = cdo.selyear('2000/2100', input='infile.nc', returnXArray=myvar)

# process on my_xarray

my_xarray_final = cdo.yearsum(input=my_xarray, returnXArray=myvar)

How could I use my_xarray as input in the yearsum CDO function?

Thanks in advance for your help,
Pauline


Replies (9)

RE: Using Xarray as input with Python CDO wrapper - Added by Ralf Mueller over 1 year ago

Hi Pauline - again ;-)

I think, this already works. See https://github.com/Try2Code/cdo-bindings/blob/master/python/test/test_cdo.py#L426

But keep in mind that internally the xarray is saved into a netcdf file https://github.com/Try2Code/cdo-bindings/blob/master/python/cdo/cdo.py#L455 because CDO can only for on data files after all. So this will create additional IO.

hth
ralf

the links might not show the version you use, but the functionality is the same since 1.3.9 I think.

RE: Using Xarray as input with Python CDO wrapper - Added by Pauline Millet over 1 year ago

Hello Ralf,

Haha, I hope you didn't miss me ;-)

Thanks for your answer.
Here is the piece of code I wrote to test whether it was working or not:

from cdo import Cdo
cdo = Cdo()

ifile="HadGEM2-ES_CCLM4-8-17_rcp45_tasAdjust.nc" 

(var,) = cdo.showname(input=ifile)
x = cdo.selyear('1985/2100', input=ifile, returnXArray=var)
y = cdo.yearsum(input=x, returnXArray=var)

But I got the following error after executing the last line:

Error in calling operator yearsum with:
>>> /usr/bin/cdo -O -s -f nc -yearsum /tmp/cdoPyaly65dcj<<<
STDOUT:
STDERR:
cdo (Abort): Too few streams specified! Operator yearsum needs 1 input stream and 1 output stream!

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/code/venv/lib/python3.10/site-packages/cdo.py", line 558, in __call__
    raise CDOException(**retvals)
cdo.CDOException: (returncode:1) 
cdo (Abort): Too few streams specified! Operator yearsum needs 1 input stream and 1 output stream!
 ::

When looking at the test you shared (https://github.com/Try2Code/cdo-bindings/blob/master/python/test/test_cdo.py#L452), it seems like the Xarray is explicitly turned to netcdf before being assigned as input to the cdo function, but maybe I'm wrong.

Also, I was wondering if a trick would exist on giving as input to CDO data retrieved from a S3 storage? I guess, from what you say, that the only way is to save it to temporary netcdf first?

Cheers,
Pauline

RE: Using Xarray as input with Python CDO wrapper - Added by Karin Meier-Fleischer over 1 year ago

Hi Pauline,

the problem is that CDO works with streams as input and not DataArrays or Datasets, so you can't use x as input to CDO.

You can use the operator chaining like:

ds_y = xr.open_dataset(cdo.yearsum(input='-selyear,2006/2010 ' + infile))
y = ds_y[var]

RE: Using Xarray as input with Python CDO wrapper - Added by Karin Meier-Fleischer over 1 year ago

Or you can do

selyear_ofile = cdo.selyear('2006/2010', input=infile)    # returns the path to the temporary output file

y = cdo.yearsum(input=selyear_ofile, returnXArray=var)

RE: Using Xarray as input with Python CDO wrapper - Added by Ralf Mueller over 1 year ago

Pauline,
I have a fix for that. Can you upload your data file for an additional test, please?

RE: Using Xarray as input with Python CDO wrapper - Added by Pauline Millet over 1 year ago

Here is a sample of my data, reduced to years 2000/2010

sample.nc (586 KB) sample.nc

RE: Using Xarray as input with Python CDO wrapper - Added by Ralf Mueller over 1 year ago

thx. I created a new release for the python bindings (1.6.0). Please give it a try with your workflow.

I added a test (https://github.com/Try2Code/cdo-bindings/blob/master/python/test/test_cdo.py#L1050) that runs what you suggested above.

Please let me know, if this works for you.

cheers
ralf

RE: Using Xarray as input with Python CDO wrapper - Added by Pauline Millet over 1 year ago

Thanks Ralf, it works like a charm!

    (1-9/9)