Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions SEP-0013.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# SEP-num -- SEP Title

| SEP | num |
|---------------|----------------------------------|
| title | A Common API for Metadata Attributes |
| author(s) | [First Last](https://orcid.org/0000-0001-8661-3825)<br>Daniel Ryan |
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| author(s) | [First Last](https://orcid.org/0000-0001-8661-3825)<br>Daniel Ryan |
| author(s) | [Daniel Ryan](https://orcid.org/0000-0001-8661-3825) |

| contact email | [email protected] |
| date-creation | 2021-09-11 |
| type | standard |
| discussion | link to discussion if available |
| status | discussion |

# Introduction
Moves are being made to develop a standardized metadata object for SunPy (and ndcube) data objects.
The benefit of this is that the same type of metadata can be accessed in the same way irrespective
of what data object is being used and what instrument the metadata has come from. To facilitate
this, a set of standardized attribute names must be established for storing and accessing commonly
used metadata in solar physics. Then a metadata object can implement a translation from the
original file/object containing the metadata file, e.g. FITS header, and the attributes.

The purpose of this SEP is to agree the names of the different metadata attributes. To start with
the list does not have to be exhaustive. We envision that it can be appended to over time. But
once an attribute name is addedit should preferably not be changed so that users can rely on a
stable, backwards compatible API.

For now, this API does not include WCS metadata and should not be linked to a specific file format,
e.g. FITS.


# SunPy Metadata API
Below is a class definition of an Metadata Abstract Base Class (ABC) for solar physics.

```python

class MetaABC():
##### Instrument info #####

@abc.abstractproperty
def observatory(self):
"""
Name of the observatory
"""

@abc.abstractproperty
def instrument(self):
"""
Name of the instrument
"""

@abc.abstractproperty
def detector(self):
"""
Name of the detector
"""

##### Data Info ####

@abc.abstractproperty
def data_processing_level(self):
"""
The level to which the data has been processed.
"""

@abc.abstractproperty
def data_version(self):
"""
The data version.
"""

##### Observer Coordinate Info #####

@abc.abstractproperty
def observer_location(self):
"""
Coordinate of observatory location.
"""

def observer_radial_velocity(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If observer_location is a SkyCoord, can't the velocity be bundled in there? (see https://docs.astropy.org/en/latest/coordinates/velocities.html for more technical info)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this suggestion :)

"""
Velocity of observer in direction of source.
"""

@abc.abstractproperty
def celestial_frame(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean? (I think this is a case where typing the return would help!) Is it the WCS? Or part of the WCS?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is trying to play the role of Map.coordinate_frame. The reason I called it celestial_frame was we don't know what the physical types of the associated data, unlike with Map.

"""
The celestial coordinate frame of the image axes.
"""

@abc.abstractproperty
def distance_to_sun(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant if you specify the observer location and observation time.

"""
Distance to Sun center from observatory.
"""

@abc.abstractproperty
def light_travel_time(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is poorly defined - for an image of the Sun for example the light travel time will be different across the image detector because the limb of the Sun is further away than disc center.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is certainly true for large fields of view. But in smaller fields of view or higher energy images where only a flare emits sufficiently to be detected it is well (or better) defined.

Having said that though, there is nothing preventing this returning a Quantity with the same shape as the spatial axes giving the light travel time for each pixel. The other Metadata PR open in this repo describing a Sliceable Metadata object would support this.

"""
Light travel time from emission source to observer.
"""

@abc.abstractproperty
def light_travel_time_to_earth(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this is redundant if you specify the observer coordinate and observation time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true. But I imagine this would still be a useful convenience property that does the calculation for the user instead of requiring them to type the couple lines of code every time.

"""
Light travel time from observer to Earth.
"""

##### Time Info #####

@abc.abstractproperty
def date_reference(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this information bundled in with the Time object that date_start/average will return?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right that the high level WCS API should return a Time object for the temporal axis. So this probably isn't needed in that case.

"""
The base time from which time axis values are measured.
"""

@abc.abstractproperty
def date_start(self):
"""
Time at which the observation(s) were started.
"""

@abc.abstractproperty
def date_average(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant if you have the start/end time? If not, how exactly is mean/representative defined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, think DATE_OBS in a FITS header. It's "the" time of the observation, however that's defined by the instrument team.

However, if the data is in an NDCube I would argue this information should be stored in .global_coords. So if we link this metadata standard with NDCube I think this property should be removed. But here I haven't required that this metadata class be used with an NDCube instance. Perhaps we should?

"""
The mean/representative time of the observation(s).
"""

@abc.abstractproperty
def date_end(self):
"""
The time at which the observation(s) were ended.
"""

@abc.abstractproperty
def exposure_time(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant given start/end time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't necessarily true. The start/end time can represent the cadence. Moreover, if there are multiple images/measurements over time, the start/end times will represent the observing duration, not the exposure time of each image.

"""
The exposure time(s) of the observation(s).
"""

##### Misc. #####

@abc.abstractproperty
def rsun_meters(self):
"""
Solar radius in units of length.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Solar radius in units of length.
Assumed radius of emmission measured from the solar center.

"""

@abc.abstractproperty
def rsun_angular(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant given observer coordinate and rsun_meters?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. But again in that case, this is still a useful convenience property. Moreover who's to say that rsun_meters is provided in the header. Perhaps only rsun_angular is.

"""
Solar radius in angular units as seen from observatory.
"""

##### Spectral Info #####

@abc.abstractproperty
def spectral_window(self):
"""
The name of the spectral window in which data has been taken.
"""

##### Imaging Info #####

@abc.abstractproperty
def filter(self):
"""
The name of the filter(s) used to make the observation.
"""

@abc.abstractproperty
def automatic_exposure_control_on(self):
"""
Whether automatic exposure control was on during observations.
"""

##### Operational Info #####

@abc.abstractproperty
def observing_mode(self):
"""
The observing mode used to make the observations.
"""

@abc.abstractproperty
def observing_mode_id(self):
"""
Identification number of the observing mode.
"""

@abc.abstractproperty
def SAA(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant given observer position/time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An SAA flag is often provided in FITS headers. So there is a philosophical question here. Is this metadata object for the minimal set of metadata from which all others can be derived? Or is it to represent the metadata attached to the data? Put another way, do we discard redundant information provided by instrument teams and ask users to recalculate it from other metadata? If we do, who's to say these will provide the same results? Where is the boundary of the SAA? It may depend on the instrument's sensitivity to the SAA. In this case a general user may come up with a different result to the more knowledgeable instrument team.

"""
Whether observer passed through the South Atlantic Anomaly during the observations.
"""

```

# Decision Rationale
This is a great idea because...