Re: More Songs about Coordinate Systems and Buildings

John Caron (caron@ucar.edu)
Wed, 06 Aug 1997 12:08:06 -0600

Comments on John Sheldon's post:

> > ...
> > 1.4 Coordinate Values.
> >
> > (Level 1) A coordinate function that is a scalar netcdf variable is
> > considered a point along its coordinate axis.
> >
> > (Level 2) A coordinate function that is multiply valued is specified by a
> > list of scalar netcdf variables enclosed in parenthesis:
> >
> >      :coordinates = "lat lon (lev_upper lev_lower lev_midpoint lev_label)";
> 
> Hmmm...like some of the other comments made about this issue, I don't
> think that "boundary" information really constitutes "coordinate"
> status.  I prefer GDT's approach, although I'd modify it so that
> different variables could use different boudaries along the same basic
> axis.  (eg, a 3-hr vs. a 6-hr window for data collection.)

I get the feeling that you have some unstated idea about what a
"coordinate" is that differs somewhat from my idea. Perhaps you could
look at my definition (in http://acd.ucar.edu/~caron/proposals.html) and
see if you agree or not. 

I am trying to make a fairly broad definition of coordinate. Any
function that obeys a few certain rules may be a coordinate.  I assume
that you are saying that this is not corresponding  to your intuitive
idea of what a coordinate is.  From some comments below, I guess that
you identify "coordinate" with "spatial coordinate", and from this
comment, you mean coordinate = "a point".

> 
> > ...
> > 1.6 Coordinate Variables. A variable with the same name as a dimension, with
> > that dimension in its domain, is the coordinate variable for that dimension.
> > It is recommended that coordinate variables be one-dimensional. In this case
> > the value of the variable must be strictly increasing or decreasing with
> > respect to the dimension index (the function is then said to be monotonic).
> >
> > (Level 2) Multi-dimensional coordinate variables, while allowed, may be
> > misleading in their association with a single dimension, and are considered
> > less desirable. Multi-dimensional coordinate variables are not in general
> > monotonic, but they must satisfy the uniqueness property of any coordinate
> > systems of which they are part.
> 
> Well, here's our old, familiar disagreement.  Your admonitions aside, I
> would really like to avoid multi-dimensional coordinate variables.  I
> think there are other ways to convey the necessary information that
> will not run counter to the long-standing convention of 1-D coordinate
> variables.  For the sake of prospective users and application
> developers, let's retain the simplicity of the current assumptions.

Frankly, I agree with you, but I was trying to include existing
practices.

> 
> > Coordinate variables define an "implicit" coordinate system for any variable
> > that uses those dimensions. For such a variable, find all dimensions with
> > coordinate variables: the implicit coordinate system is the one composed of
> > that list of coordinate variables. This can be turned off by adding a global
> > or variable attribute with name "coordinates.implicit" and value equal to a
> > blank string or the string "none". It is recommended that when multiple
> > coordinate systems are intended, that all be explicitly defined.
> 
> I'm not sure what purpose your "coordinates.implicit" serves.  Could
> you give a CDL example?  Wouldn't a global "coordinates" attribute
> imply a default?  Or, by "implicit" do you mean that the coordinate
> system should be inferred somehow from the qualities of the coordinate
> variables without actually having to list them (a la COARDS I)?

In order to allow coordinate variables (1D or not), I need to formally
say what is the coordinate system that they implicitly define. Then I
thought it would be a good idea to be able to explicitly "turn off" the
use of coordinate variables. (I admit I don't have a motivating example
in mind as to why you would need to turn them off.) So
	:coordinates.implicit = "none";
is just the way to turn off the use of coordinate variables to define a
coordinate system.


> 
> > ...
> > ----------------------------------------------------------------------------
> >
> > Examples
> >
> > Shorthand "solutions" of the motivating examples :
> 
> I'll combine parts of your mail and offer an alternative set of
> solutions here.  The two approaches are so close that I think little
> additional explanation is required.  Basically, my approach differs
> in the following ways:
> 
>    a) define global "coordinate maps", a la Gary Granger
> 
>    b) the "coordinate map" name should have a prefix indicating the
>         basic coordinate system (cartesian, cylindrical, spherical,
>         geodetic, ...)
> 
>    c) the specific variables referred to in the "coordinate map"
>         should be assigned to the generic axes of the basic coordinate
>         system
>            cartesian   : "X", "Y", and "Z"
>            cylindrical : "rho", "theta", and "z"
>            spherical   : "theta", "phi", and "r"
>            geodetic    : "latitude", "longitude", and "altitude"

So here is where it seems you are restricting your attention to only
spatial coordinate systems. I want to embed these as special cases in
the general case.


> >
> >   3. projective geometry:
> >       var(lat, lon)
> >           lat(lat,lon)
> >           lon(lat,lon)
>   My solution:
>             :coordinates="cartesian_1 geodetic_1";
>             :cartesian_1="X=x, Y=y";
>             :geodetic_1="latitude=lat, longitude=lon";

so i see that you are using <keyword>=<value> pairs, where the keywords
are all "standard" spatial coordinate names.


> >
> >   5. edge coordinates, level is some kind of altitude coordinate:
> >
> >      var(level)
> >           lev_bottom(level)
> >           lev_top(level)
> 
>   Your solution:
> >           :coordinates = "(lev_bottom lev_top)";
> >           float lev_bottom( level);
> >                 lev_bottom:component = "lower_bound";
> >           float lev_top( level);
> >                 lev_top:component = "upper_bound";
>   My solution:
>      These are not really "coordinates", but "bounds" of a "cell"
>      around the actual data point.

Here is where i see that for you "coordinate" = "point".

> 
> >   6. non- georeferencing coordinates. Up to now, all the examples have been
> >      georeferencing coordinates. A different coordinate system that we use
> >      in radiative transfer codes is
> >
> >         var(lev, wavelength)
> 
>   Your solution:
> >           :coordinates = "lev wavelength";
>   My solution:
>      This is not really a spatio-temporal coodinates problem, but we'll
>      stretch it a bit here:
>             :coordinates = "cartesian_1";
>             :cartesian_1="X=wavelength, Z=lev";

here you are explicit that for you "coordinate system" =
"spatio-temporal coordinate system". But clearly wavelength is not a
spatial coordinate; yet it certainly will have some coordinate value
associated with each index. This is why I want a more general definition
of coordinate system.

> >
> >   7. vector valued variables, for example:
> >       vector(lev, 3)
> >       velocity(lat,lon,component)
> >           component(3) = "u", "v", "w"
> 
>   Your solution:
> >           :coordinates = "lev";
> >           :coordinates = "lat lon components";
>   My solution:
>       This is not a "coordinates" issue.  "Associating" separate scalar
>       quantities into a vector quantity is a useful goal, but I haven't
>       had time to give it enough thought.

The u,v,w example is tricky because there is another level of
information we want to associate here, namely the spatial direction of
each of those components. All I intended here was to label the three
numbers. 

There is some interesting problem here on specifying a wind vector,
having both a location and a direction. Anyone want to offer an axample
and solution? 

> 
> >
> >   8. correlations, using a dimension more than once:
> >       precip(time, npoints)
> >       precip.correlation( npoints, npoints)
> >           lat(npoints)
> >           lon(npoints)
> 
>   Your solution:
> >       - will need some notation not yet formally proposed, eg:
> >           :coordinates = "lat(npoints,) lon(npoints,) lat(,npoints)"
>   My solution:
>       Not applicable..."correlation" does not possess "coordinates" the
>       way we think of them.  I suppose you could try to document how
>       the correlation was calculated (ie, the lat-lon location
>       of the points being correlated), but I think that is probably
>       something to be addressed using variable attributes (perhaps
>       GDT's "associate").

I think of the coordinate of a correlation as (coordinate of point 1,
coordinate of point 2). This would likely be a point in R6.


> >
> >  10. moving coordinate system. For example, satellite images tracking a
> >      tropical hurricane keep the coordinate system centered on the hurricane
> >      as it moves:
> >           pressure(time, x, y)
> >           lat(time, x, y)
> >           lon(time, x, y)
> 
>   Your solution:
> >           :coordinates.geodetic = "lon lat pressure";
>   My solution:
>      What is the "data" variable here?  It appears to be "pressure",
>      as if you are monitoring sea-level pressure.  It that case,
>      "pressure" should probably not be in your list of coordinates,
>      and my solution would be:
>             :coordinates="geodetic_1";
>             :geodetic_1"=latitude=lat, longitude=lon";

Perhaps the example should read:
	reflectivity(time, i, j)
	   pressure(time, i, j)
           lat(time, i, j)
           lon(time, i, j)
and my solution is:
	reflectivity:coordinates.geodetic = "lon, lat, pressure";

Perhaps someone who knows more about satelite data could help here?

> 
> >
> >  11. multiple time coordinates:
> >
> >       var(time)
> >           year(time)
> >           day_of_year(time)
> >           second_of_day(time)
> 
>   Your solution:
> >           :coordinates = "year, day_of_year, second_of_day";
> 
>       ? This makes it appear that "var" is occupying a 3-dimensional
>         space.  Or are you assuming that that fact that the units on
>         "year", "day_of_year", and "second_of_day" will imply that
>         there is really only 1 axis?
> 
>   My solution:
>     short time(time);  // simply index values, unless you
>                        //  have a traditional value, too
>           time:component="year, day_of_year, second_of_day";  // a la GDT

I admit I havent dealt with this example.

In the GDT solution I dislike putting indices in the time(time)
variable; The semantics of "component" just gives you a 3-tuple so you
lose the fact that year.day.second is ordered. 

I guess I would lean towards a seperate "coordinates.time = something"
convention to capture the various things we need in time coordinates.
 
> 
> >    and the famous NUWG case:
> >       var(time)
> >           generate_time(time)
> >           valid_time(time)
> 
>   Your solution:
> >           :coordinates = "generate_time, valid_time";
>   My solution:
>       time:time="generate_time, valid_time";
>    or
>       time:associate="generate_time, valid_time";

Shouldnt this be a "component", not an "associate" in GDT?

> 
> >
> >  12. sparse data variables. Adapted from Harvey Davies' example:
> >       soil.temperature(time, land_point)
> >           land_index(lat, lon) // if over land = land_point index, else -1
> >           lat(lat)
> >           lon(lon)
> >           time(time)
> >
> >     or another way of getting a similar result:
> >       soil.temperature(time, land_point)
> >           latidx(land_point) // latitude index of ith land point
> >           lonidx(land_point) // longitude index of ith land point
> >           lat(lat)
> >           lon(lon)
> >           time(time)
> 
>   Your solution:
> >           :coordinates = "lat*latidx, lon*lonidx, time"
>       I am a bit apprehensive of adding a "language" with a certain
>       nomenclature that has to be parsed out.

I agree, but I wanted to see how useful functional composition might be;
if you allow it here then you need no new semantics to find the
(lat,lon) point of each sparse variable.

> 
>   My solution:
>     Go back to the first suggestion above...
>     I am not hard-over on this, but I like the idea of having a
>     "mask" readily available for visual referral:
>         float soil.temperature(time, land_point)
>               soil.temperature:mask="land_point=land_index";
>         short land_index(lat,lon);  // could also be 0's and 1's
>         :coordinates="geodetic_1";
>         :geodetic_1"=latitude=lat, longitude=lon";
> 
>       So, at land_point=i, "mask" tells you to look at the "land_index"
>       array to find the point with a value of "i" (or, if array is
>       simple 0's and 1's, find the i-th point that is "1"), then get
>       the latitude and longitude from "lat" and "lon".

The use of a mask this way is fairly common and elegent in its way; it
does introduce a different mechanism to specify coordinates.

Thanks for your thoughts...