Skip to content

Latest commit

 

History

History
114 lines (84 loc) · 4.66 KB

SEP-0003.md

File metadata and controls

114 lines (84 loc) · 4.66 KB

SEP-0003 - Physical Units in SunPy

SEP 3
title Physical Units in SunPy
author(s) Steven Christe
contact email steven.d.christe@nasa.gov
date-creation 2014-04-22
type standard
discussion #7
status accepted

Introduction

Using quantities with units is a great idea because it less likely that mistakes will be made and units can be easily converted as needed. This SEP defines how physical quantities should be dealt with in SunPy.

Detailed Description

All user-facing function/object arguments which accept physical quantities as input MUST accept astropy quantities. The same standards should be followed for functions whose output is a physical quantity, they should output an astropy quantity. For the sake of consistency, functions/objects should strive to not convert the units given by the user meaning that if a users hands a length in meters than the output should also use meters regardless of how complex the resulting quantity might be (e.g. flux).

Use of astropy quantities throughout code is also expected. In cases where performance may be significantly impacted by the use of quantities, private (i.e. non-user-facing) wrapper functions may be used which accept physical quantities in the form of pure numbers. However in these cases, variable name used for both input and output should strive to carry the name of the unit (e.g. x_arcsec, length_meters, photons_flux) and the excepted input and output units must be declared in the doc string.

Usage Examples

Simple Example

def get_area_of_square(side_length):
    """Compute the area of a square.

    Parameters
    ----------
    side_length : `~astropy.units.quantity.Quantity`
        Side length of the square

    Returns
    -------
    area : `~astropy.units.quantity.Quantity`
        Area of the square.
    """
    if not isinstance(a, Quantity):
        raise TypeError("Expecting Quantity")

    return (side_length ** 2)

Advanced Example

In this example, a function (other_function) is needed in some_function which does not play well with quantities. In this case, a private function (_private_wrapper_function) is defined (see below) to wrap other_function. The quantity is converted to a dimensional number with a known unit and passed to the _private_wrapper_function. Afterwards the result (whose units should be known) is then converted back to a quantity to be returned by some_function.

def some_function(length):
    """Does something useful.

    Parameters
    ----------
    length : `~astropy.units.quantity.Quantity`
        A length.

    Returns
    -------
    length : `~astropy.units.quantity.Quantity`
        Another length
    """
    if not isinstance(a, Quantity):
        raise TypeError("Expecting Quantity")

    # the following function either
    # a] does not accept Quantities
    # b] is slow if using Quantities
    result_meters = _private_wrapper_function(length.convert('meters').value)

    # now convert back to a quantity
    result = Quantity(result_meters, 'meters')

    return result

In the following example, the function is itself not quantity-friendly either because it is expected to deal with millions of quantities or for some other appropriate reason.

def _private_wrapper_function(length_meters):
    """Does something else useful.

    Parameters
    ----------
    many_lengths_meters : `numpy.ndarray`
        Lengths in ``m``.

    Returns
    -------
    other_length_meters : `numpy.ndarray`
        Lengths in ``m``
    """

    # do something with length_meters
    result = other_function(length_meters)

    return result_meters

References

Decision Rationale

This SEP was accepted unanimously by the SunPy board on 9-Jun-2014 because everyone knows that units are important except for computer code...until now!