Skip to content
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

Alternate grid mappings for geometry containers #156

Closed
twhiteaker opened this issue Mar 1, 2019 · 16 comments
Closed

Alternate grid mappings for geometry containers #156

twhiteaker opened this issue Mar 1, 2019 · 16 comments
Labels
enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format

Comments

@twhiteaker
Copy link
Contributor

Title: Alternate grid mappings for geometry containers
Moderator: @davidhassell
Requirement Summary:
Allow geometries to have a grid_mapping different than the data variable. For example, data variable coordinates could be in geographic coordinates, while coordinates for watershed polygons could be in a projected coordinate system.

Technical Proposal Summary:
Allow the grid_mapping attribute value on the geometry container to differ from the grid_mapping attribute on the data variable, provided the auxiliary coordinates do not have the nodes as bounds.

Benefits: This benefits those who have defined their geometries in a coordinate system different than the coordinates used for the data variable.

Status Quo:
According to Chapter 7, a data variable's coordinate variables can have a nodes attribute which identifies the equivalent variable from a geometry. Thus, nodes act as bounds to the coordinates, and bounds are considered as metadata to the coordinates. Therefore, following this logic, bounds can't have a different coordinate system.

Detailed Proposal:
Allow the different grid mapping on the geometry container variable, provided the auxiliary coordinates do not have the nodes as bounds, e.g.

dimensions:
  instance = 2 ;
  node = 5 ;
  time = 4 ;
variables:
  int time(time) ;
    time:units = "days since 2000-01-01" ;
  double lat(instance) ;                     
    lat:units = "degrees_north" ;
    lat:standard_name = "latitude" ;
  double lon(instance) ;                  
    lon:units = "degrees_east" ;
    lon:standard_name = "longitude" ;
  int datum ;
    datum:grid_mapping_name = "latitude_longitude" ;
    datum:longitude_of_prime_meridian = 0.0 ;
    datum:semi_major_axis = 6378137.0 ;
    datum:inverse_flattening = 298.257223563 ;
  int Lambert_Conformal;
    Lambert_Conformal:grid_mapping_name = "lambert_conformal_conic";
    Lambert_Conformal:standard_parallel = 25.0;
    Lambert_Conformal:longitude_of_central_meridian = 265.0;
    Lambert_Conformal:latitude_of_projection_origin = 25.0;
  int geometry_container ;
    geometry_container:geometry_type = "line" ;
    geometry_container:node_count = "node_count" ;
    geometry_container:node_coordinates = "x y" ;
    geometry_container:grid_mapping = "Lambert_Conformal" ;
  int node_count(instance) ;
  double x(node) ;
    x:units = "degrees_east" ;
    x:standard_name = "longitude" ;
    x:axis = "X" ;
  double y(node) ;
    y:units = "degrees_north" ;
    y:standard_name = "latitude" ;
    y:axis = "Y" ;
  double someData(instance, time) ;
    someData:coordinates = "time lat lon" ;
    someData:grid_mapping = "datum" ;
    someData:geometry = "geometry_container" ;
// global attributes:
  :Conventions = "CF-1.8" ;
  :featureType = "timeSeries" ;

"lat" and "lon" could have bounds, so long as they not "y" and "x".

@twhiteaker
Copy link
Contributor Author

Conformance edits:
twhiteaker/Conformance@9098401

Ch7 edits:
twhiteaker@bfad9fd

@davidhassell
Copy link
Contributor

Thanks Tim - this looks good to me.

I was surprised to see the auxiliary coordinates having "nodes" attributes in https://github.com/twhiteaker/cf-conventions/blob/master/ch07.adoc - I thought that that idea had been rejected in favour of just using the "bounds" attribute? I will try to dig out the correspondence on this to check ....

David

@twhiteaker
Copy link
Contributor Author

The nodes change happened due to an email discussion, which in hindsight really should've been captured as a GitHub issue! I'll paste the initial email from David Hassell which captures the motivation for the change.

from David Hassell, 2018-07-10, trimmed for brevity

I fear that I made a slight mistake when I suggested that a coordinate variable should point to its node variable with the "bounds" attribute. The cross referencing is fine, but the use of the "bounds" attribute is problematic.

The node variable has its own dimension, so this will confuse applications that expect the bounds variable to have have the same dimensions as the coordinate variable, with a trailing dimension for the number of cell vertices.

There is, of course, a precedent for storing bounds with a different attribute, to alert the user that the bounds are not all they might seem to be: "climatology".

I propose a new attribute on a coordinate variable called "nodes" to point to the node variable. Then geometry-unaware applications will not break, and geometry-aware applications will be fine.

P.S. This occurred to me whilst trying to read geometry netCDF files with python CFDM reference implementation, which is a good example of why having such an implementation is a good idea, I think: The proof of the pudding is in the eating

@davidhassell
Copy link
Contributor

Tim,

Thanks for digging this out, and pasting it into GitHub. I'm as happy now as I was in July with the decision to use "nodes". I think that the key point is to prevent any attempt to parse node coordinates as if they were "normal" cell bounds.

David

@davidhassell davidhassell added the enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format label Mar 12, 2019
@davidhassell
Copy link
Contributor

davidhassell commented Mar 13, 2019

I wonder if both grid mapping should be linked from the data variable, as allowed since CF-1.6:

double someData(instance, time) ;
    someData:coordinates = "time lat lon" ;
    someData:grid_mapping = "datum: lat lon Lambert_Conformal: x y" ;
    someData:geometry = "geometry_container" ;

@twhiteaker
Copy link
Contributor Author

What's the motivation for adding the projected grid mapping to the data variable? Might it be confusing that x and y will likely use a different dimension than the data variable?

@davidhassell
Copy link
Contributor

That's a good point, about the fact that x and y will not span a data dimension variable.

However, in the event that there are no coordinate variables, the data variable's grid mapping does indeed refer to x and y:

int geometry_container ;
    geometry_container:geometry_type = "line" ;
    geometry_container:node_count = "node_count" ;
    geometry_container:node_coordinates = "x y" ;
    geometry_container:grid_mapping = "Lambert_Conformal" ;
double someData(instance, time) ;  // NO coordinates attirbute
    someData:grid_mapping = "Lambert_Conformal" ;
    someData:geometry = "geometry_container" ;

so I think it would be generally more consistent for the data variable to always refer to the grid mapping of the node coordinates.

@twhiteaker
Copy link
Contributor Author

OK, that's fine with me then.

@twhiteaker
Copy link
Contributor Author

The relevant revised text would read:

If a coordinates attribute is carried by the geometry container variable
or its parent data variable, then those coordinate variables that have a
meaningful correspondence with node coordinates are indicated as such by a
nodes attribute that names the corresponding node coordinates, but only if
the grid_mapping associated with the geometry node variables is the same as that of
the coordinate variables. If a different grid mapping is used, then the provided
coordinates must not have the nodes attribute.

twhiteaker added a commit to twhiteaker/cf-conventions that referenced this issue Mar 22, 2019
Make the comparison between grid mappings, between the node and coordinate variables.
@twhiteaker
Copy link
Contributor Author

It's better to see the pull requests for the latest edits.

#158

cf-convention/Conformance#6

@JonathanGregory
Copy link
Contributor

I agree, this change makes sense.

At the moment, App A permits a grid_mapping attribute only for data variables, so perhaps this need to be changed to allow if for geometry container variables too. I see that App A begins by stating "All CF attributes are listed here except for those that are used to describe grid mappings. See Appendix F for the grid mapping attributes" but that will not be true unless the geometry container attributes are added to App A. I don't think that's been done, has it? Alternative, as for grid mappings, there could be a separate appendix to list to geometry container attributes.

Jonathan

@twhiteaker
Copy link
Contributor Author

I believe this is already resolved in App A on GitHub.

App A at cfconventions.org is out of date.

@JonathanGregory
Copy link
Contributor

Ah, OK, thanks. It's out of date in the working version of 1.8 as well. I wonder why this isn't updated.

@twhiteaker
Copy link
Contributor Author

So is this issue essentially resolved, pending acceptance of my pull request?

I realize now I should have submitted separate pull requests for this issue vs. the more controversial geometry dimension issue. Still learning!

@JonathanGregory
Copy link
Contributor

I'm happy with this, yes thank you. Jonathan

@dblodgett-usgs
Copy link
Contributor

Fixed in #158 and cf-convention/Conformance#6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format
Projects
None yet
Development

No branches or pull requests

4 participants