Skip to content

coordinate variable not written in netcdf file in some cases #733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rafa-guedes opened this issue Jan 29, 2016 · 6 comments
Closed

coordinate variable not written in netcdf file in some cases #733

rafa-guedes opened this issue Jan 29, 2016 · 6 comments

Comments

@rafa-guedes
Copy link
Contributor

I came across a situation where my coordinate variable was not dumped as a variable in the output netcdf file using dataset.to_netcdf. In my case I managed to fix it by simply adding variable attributes to this coordinate variable (which didn't have any).

The situation where that happened was while creating a sliced dataset with dataset.isel_points method which automatically defines a new coordinate called points in the sliced dataset. If I dump that dataset as is, the coordinate isn't written as a variable in the netcdf. adding attributes to points however changes that. Here is an example:

In [1]: import xarray as xr

In [2]: ds = xr.open_dataset('netcdf_file_with_longitude_and_latitude.nc')

In [3]: ds
Out[3]: 
<xarray.Dataset>
Dimensions:    (latitude: 576, longitude: 1152, time: 745)
Coordinates:
  * latitude   (latitude) float64 -89.76 -89.45 -89.14 -88.83 -88.52 -88.2 ...
  * longitude  (longitude) float64 0.0 0.3125 0.625 0.9375 1.25 1.562 1.875 ...
  * time       (time) datetime64[ns] 1979-01-01 1979-01-01T01:00:00 ...
Data variables:
    ugrd10m    (time, latitude, longitude) float64 0.2094 0.25 0.2799 0.3183 ...
    vgrd10m    (time, latitude, longitude) float64 -5.929 -5.918 -5.918 ...

In [4]: ds2 = ds.isel_points(longitude=[0], latitude=[0]).reset_coords()

In [5]: ds2
Out[5]: 
<xarray.Dataset>
Dimensions:    (points: 1, time: 745)
Coordinates:
  * time       (time) datetime64[ns] 1979-01-01 1979-01-01T01:00:00 ...
  * points     (points) int64 0
Data variables:
    latitude   (points) float64 -89.76
    vgrd10m    (points, time) float64 -5.929 -6.078 -6.04 -5.958 -5.858 ...
    ugrd10m    (points, time) float64 0.2094 0.109 0.008546 -0.09828 -0.2585 ...
    longitude  (points) float64 0.0

In [6]: ds2['points'].attrs
Out[6]: OrderedDict()

In [7]: ds2.to_netcdf('/home/rafael/ncout1.nc')

In [8]: ds2['points'].attrs.update({'standard_name': 'site'})

In [9]: ds2['points'].attrs
Out[9]: OrderedDict([('standard_name', 'site')])

In [10]: ds2.to_netcdf('/home/rafael/ncout2.nc')

Here is the ncdump output for these two files:

$ ncdump -h /home/rafael/ncout1.nc
netcdf ncout1 {
dimensions:
    time = 745 ;
    points = 1 ;
variables:
    double time(time) ;
        time:_FillValue = 9.999e+20 ;
        string time:long_name = "verification time generated by wgrib2 function verftime()" ;
        time:reference_time = 283996800. ;
        time:reference_time_type = 0 ;
        string time:reference_date = "1979.01.01 00:00:00 UTC" ;
        string time:reference_time_description = "kind of product unclear, reference date is variable, min found reference date is given" ;
        string time:time_step_setting = "auto" ;
        time:time_step = 3600. ;
        string time:units = "seconds since 1970-01-01" ;
        time:calendar = "proleptic_gregorian" ;
    double latitude(points) ;
        string latitude:units = "degrees_north" ;
        string latitude:long_name = "latitude" ;
    double vgrd10m(points, time) ;
        string vgrd10m:short_name = "vgrd10m" ;
        string vgrd10m:long_name = "V-Component of Wind" ;
        string vgrd10m:level = "10 m above ground" ;
        string vgrd10m:units = "m/s" ;
    double ugrd10m(points, time) ;
        string ugrd10m:short_name = "ugrd10m" ;
        string ugrd10m:long_name = "U-Component of Wind" ;
        string ugrd10m:level = "10 m above ground" ;
        string ugrd10m:units = "m/s" ;
    double longitude(points) ;
        string longitude:units = "degrees_east" ;
        string longitude:long_name = "longitude" ;
}
$ ncdump -h /home/rafael/ncout2.nc
netcdf ncout2 {
dimensions:
    time = 745 ;
    points = 1 ;
variables:
    double time(time) ;
        time:_FillValue = 9.999e+20 ;
        string time:long_name = "verification time generated by wgrib2 function verftime()" ;
        time:reference_time = 283996800. ;
        time:reference_time_type = 0 ;
        string time:reference_date = "1979.01.01 00:00:00 UTC" ;
        string time:reference_time_description = "kind of product unclear, reference date is variable, min found reference date is given" ;
        string time:time_step_setting = "auto" ;
        time:time_step = 3600. ;
        string time:units = "seconds since 1970-01-01" ;
        time:calendar = "proleptic_gregorian" ;
    double latitude(points) ;
        string latitude:units = "degrees_north" ;
        string latitude:long_name = "latitude" ;
    double vgrd10m(points, time) ;
        string vgrd10m:short_name = "vgrd10m" ;
        string vgrd10m:long_name = "V-Component of Wind" ;
        string vgrd10m:level = "10 m above ground" ;
        string vgrd10m:units = "m/s" ;
    double ugrd10m(points, time) ;
        string ugrd10m:short_name = "ugrd10m" ;
        string ugrd10m:long_name = "U-Component of Wind" ;
        string ugrd10m:level = "10 m above ground" ;
        string ugrd10m:units = "m/s" ;
    double longitude(points) ;
        string longitude:units = "degrees_east" ;
        string longitude:long_name = "longitude" ;
    int64 points(points) ;
        points:standard_name = "site" ;
}
@shoyer
Copy link
Member

shoyer commented Jan 29, 2016

This is an unadvertised feature, though I agree that it may be more trouble than it's worth -- xarray implicitly creates coordinates like range(n) when coordinates corresponding to a dimension are missing from the netCDF file.

The original intent (see #245) was for more faithful roundtripping of netCDF files, which may not have all coordinate variables defined. Arguably, it would make more sense to only do this when a certain encoding parameter is found (e.g., {'trivial_index': True}), indicating that xarray created the coordinate itself.

@shoyer
Copy link
Member

shoyer commented Jan 30, 2016

At the very least, we should advertise this feature in the documentation. But given how surprising people find it, it might be even better to remove it...

@rafa-guedes
Copy link
Contributor Author

I personally find it useful - maybe not too intuitive though that the behaviour changes depending on whether there are attrs defined for that coordinate variable or not. I agree some documentation on this would be definitely helpful!

@wilhelmsen
Copy link

I also find it useful, now that I understand it.

But I also find it useful to know if the xarray coordinate is a netcdf coordinate or netcdf dimension: "A variable with the same name as a dimension is called a coordinate variable". But I guess that is the same as "indicating that xarray created the coordinate itself", as @shoyer mentioned above?

@stale
Copy link

stale bot commented Dec 25, 2020

In order to maintain a list of currently relevant issues, we mark issues as stale after a period of inactivity

If this issue remains relevant, please comment here or remove the stale label; otherwise it will be marked as closed automatically

@stale stale bot added the stale label Dec 25, 2020
@kmuehlbauer
Copy link
Contributor

Given the age of this issue, let's close it. Please reopen with updated MCVE, if the issue still persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants