Summary
Create a document that serves as the coordinate creation spec. This issue is concurrent with coordinate class naming (#53). Ideally, this issue precedes coordinate documentation (#4) and testing (#3) -- it would be nice to update the tests to match the spec, and then update the code (and docstrings) to pass the tests. This issue also precedes the user guide (#45).
Background
Coordinate creation is a challenging issue because it needs to be sufficiently general in order to cover enough use cases while remaining both concise as well as sufficiently simple/concrete/usable for a new user. We have overhauled coordinate creation a few times in the past, and it's time to really settle on a spec.
Current Status
Coordinate creation involves two main components:
- creation of the coordinate values of a single dimension (currently the
~Coord
classes)
- assembling one or more of these 1d coordinates together with relational information (currently the
Coordinate
class)
develop
The Coordinate
class initialization accepts either keyword arguments or a stacked dictionary, which define the coordinates values for each dimension (key) with either ~Coord
objects or shortcuts that are mapped to ~Coord
objects. Keys with an underscore encode relational information (stacking). All of the coordinate creation options are available in one place.
# a few options
Coordinate({'lat_lon':(Coord([1, 2, 3, 4]), Coord([10, 20, 30, 40])), time:Coord('2018-01-01')})
Coordinate({'lat_lon':([1, 2, 3, 4], [10, 20, 30, 40]), time:'2018-01-01'})
Coordinate(lat_lon=([1, 2, 3, 4], [10, 20, 30, 40]), time='2018-01-01')
The Coordinate
class initialization requires a stacked dictionary with coordinate values for each dimension (key) defined by ~Coord
objects. Keys with an underscore encode relational information (stacking). The stacked dictionary argument matches the Coordinate.stacked_dict
property.
A coordinate
helper function accepts keyword arguments which define the coordinate values for each dimension (key) with shortcuts that are mapped to ~Coord
objects.
Coordinate({'lat_lon':(Coord([1, 2, 3, 4]), Coord([10, 20, 30, 40])), time:Coord('2018-01-01')})
podpac.coordinate('lat_lon'=([1, 2, 3, 4], [10, 20, 30, 40]), time='2018-01-01')
@mlshapiro has suggested replacing the keyword arguments with a list of values and second argument for dimension labels. This is similar to xarray DataArray creation: the main data and its structure are provided as a positional argument, with labeling meta-data passed as a second keyword argument. The values would accept either ~Coord
objects or shortcuts that are mapped to ~Coord
objects.
Coordinate([([1, 2, 3, 4], [10, 20, 30, 40]), '2018-01-01'], dims=[('lat', 'lon'), 'time'])
Additional considerations
We discussed the pros and cons of putting all of the options into Coordinate
class initialization vs. using factory functions, with general support for a spec with (potentially multiple) factory functions for common use-cases. The Coordinate
initialization could remain strict, explicit, and general while factory functions would be easy-to-use, concise, and extensible.