diff --git a/astropy-4.0.2.tar.gz b/astropy-4.0.2.tar.gz
deleted file mode 100644
index d48dad6..0000000
--- a/astropy-4.0.2.tar.gz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4014e472cc7d3ca225524bf56bf4087042cc564849cfc528c435414c2f2f4b7e
-size 7756064
diff --git a/astropy-4.1.tar.gz b/astropy-4.1.tar.gz
new file mode 100644
index 0000000..b2b83ed
--- /dev/null
+++ b/astropy-4.1.tar.gz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a3bad6e1c2619135ad33e4d80452866eb9468f610bf00754da4001c63c1f7049
+size 7835617
diff --git a/astropy-pr10329-unbundle-erfa_4.1.patch b/astropy-pr10329-unbundle-erfa_4.1.patch
new file mode 100644
index 0000000..6cf1182
--- /dev/null
+++ b/astropy-pr10329-unbundle-erfa_4.1.patch
@@ -0,0 +1,38122 @@
+Index: astropy-4.1/astropy/conftest.py
+===================================================================
+--- astropy-4.1.orig/astropy/conftest.py
++++ astropy-4.1/astropy/conftest.py
+@@ -79,7 +79,7 @@ def pytest_configure(config):
+ os.mkdir(os.path.join(os.environ['XDG_CACHE_HOME'], 'astropy'))
+
+ config.option.astropy_header = True
+-
++ PYTEST_HEADER_MODULES['PyERFA'] = 'erfa'
+ PYTEST_HEADER_MODULES['Cython'] = 'cython'
+ PYTEST_HEADER_MODULES['Scikit-image'] = 'skimage'
+ PYTEST_HEADER_MODULES['asdf'] = 'asdf'
+Index: astropy-4.1/astropy/coordinates/builtin_frames/cirs_observed_transforms.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/builtin_frames/cirs_observed_transforms.py
++++ astropy-4.1/astropy/coordinates/builtin_frames/cirs_observed_transforms.py
+@@ -6,13 +6,13 @@ Currently that just means AltAz.
+ """
+
+ import numpy as np
++import erfa
+
+ from astropy import units as u
+ from astropy.coordinates.baseframe import frame_transform_graph
+ from astropy.coordinates.transformations import FunctionTransformWithFiniteDifference
+ from astropy.coordinates.representation import (SphericalRepresentation,
+ UnitSphericalRepresentation)
+-from astropy import _erfa as erfa
+
+ from .cirs import CIRS
+ from .altaz import AltAz
+Index: astropy-4.1/astropy/coordinates/builtin_frames/ecliptic_transforms.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/builtin_frames/ecliptic_transforms.py
++++ astropy-4.1/astropy/coordinates/builtin_frames/ecliptic_transforms.py
+@@ -3,6 +3,7 @@
+ """
+ Contains the transformation functions for getting to/from ecliptic systems.
+ """
++import erfa
+
+ from astropy import units as u
+ from astropy.coordinates.baseframe import frame_transform_graph
+@@ -13,7 +14,6 @@ from astropy.coordinates.transformations
+ from astropy.coordinates.matrix_utilities import (rotation_matrix,
+ matrix_product,
+ matrix_transpose)
+-from astropy import _erfa as erfa
+
+ from .icrs import ICRS
+ from .gcrs import GCRS
+@@ -54,7 +54,7 @@ def _obliquity_only_rotation_matrix(obl=
+ # The default value is the IAU 1980 value for J2000,
+ # which is computed using obl80 from ERFA:
+ #
+- # obl = _erfa.obl80(EQUINOX_J2000.jd1, EQUINOX_J2000.jd2) * u.radian
++ # obl = erfa.obl80(EQUINOX_J2000.jd1, EQUINOX_J2000.jd2) * u.radian
+ return rotation_matrix(obl, "x")
+
+
+Index: astropy-4.1/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py
++++ astropy-4.1/astropy/coordinates/builtin_frames/icrs_cirs_transforms.py
+@@ -6,6 +6,7 @@ anything in between (currently that mean
+ """
+
+ import numpy as np
++import erfa
+
+ from astropy import units as u
+ from astropy.coordinates.baseframe import frame_transform_graph
+@@ -14,13 +15,12 @@ from astropy.coordinates.representation
+ CartesianRepresentation,
+ UnitSphericalRepresentation,
+ CartesianDifferential)
+-from astropy import _erfa as erfa
+
+ from .icrs import ICRS
+ from .gcrs import GCRS
+ from .cirs import CIRS
+ from .hcrs import HCRS
+-from .utils import get_jd12, aticq, atciqz, get_cip, prepare_earth_position_vel
++from .utils import get_jd12, aticq, atciqz, pav2pv, get_cip, prepare_earth_position_vel
+
+
+ # First the ICRS/CIRS related transforms
+@@ -117,7 +117,7 @@ def icrs_to_gcrs(icrs_coo, gcrs_frame):
+ # get the position and velocity arrays for the observatory. Need to
+ # have xyz in last dimension, and pos/vel in one-but-last.
+ # (Note could use np.stack once our minimum numpy version is >=1.10.)
+- obs_pv = erfa.pav2pv(
++ obs_pv = pav2pv(
+ gcrs_frame.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
+ gcrs_frame.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))
+
+@@ -160,7 +160,7 @@ def icrs_to_gcrs(icrs_coo, gcrs_frame):
+ def gcrs_to_icrs(gcrs_coo, icrs_frame):
+ # set up the astrometry context for ICRS<->GCRS and then convert to BCRS
+ # coordinate direction
+- obs_pv = erfa.pav2pv(
++ obs_pv = pav2pv(
+ gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
+ gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))
+
+@@ -218,7 +218,7 @@ def gcrs_to_hcrs(gcrs_coo, hcrs_frame):
+
+ # set up the astrometry context for ICRS<->GCRS and then convert to ICRS
+ # coordinate direction
+- obs_pv = erfa.pav2pv(
++ obs_pv = pav2pv(
+ gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
+ gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))
+
+Index: astropy-4.1/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py
++++ astropy-4.1/astropy/coordinates/builtin_frames/intermediate_rotation_transforms.py
+@@ -7,11 +7,11 @@ rotations without aberration corrections
+ """
+
+ import numpy as np
++import erfa
+
+ from astropy.coordinates.baseframe import frame_transform_graph
+ from astropy.coordinates.transformations import FunctionTransformWithFiniteDifference
+ from astropy.coordinates.matrix_utilities import matrix_transpose
+-from astropy import _erfa as erfa
+
+ from .gcrs import GCRS, PrecessedGeocentric
+ from .cirs import CIRS
+Index: astropy-4.1/astropy/coordinates/builtin_frames/utils.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/builtin_frames/utils.py
++++ astropy-4.1/astropy/coordinates/builtin_frames/utils.py
+@@ -7,10 +7,10 @@ the ``builtin_frames`` package.
+
+ import warnings
+
++import erfa
+ import numpy as np
+
+ from astropy import units as u
+-from astropy import _erfa as erfa
+ from astropy.time import Time
+ from astropy.utils import iers
+ from astropy.utils.exceptions import AstropyWarning
+@@ -125,6 +125,16 @@ def norm(p):
+ return p / np.sqrt(np.einsum('...i,...i', p, p))[..., np.newaxis]
+
+
++def pav2pv(p, v):
++ """
++ Combine p- and v- vectors into a pv-vector.
++ """
++ pv = np.empty(np.broadcast(p, v).shape[:-1], erfa.dt_pv)
++ pv['p'] = p
++ pv['v'] = v
++ return pv
++
++
+ def get_cip(jd1, jd2):
+ """
+ Find the X, Y coordinates of the CIP and the CIO locator, s.
+@@ -344,7 +354,7 @@ def prepare_earth_position_vel(time):
+
+ # Also prepare earth_pv for passing to erfa, which wants it as
+ # a structured dtype.
+- earth_pv = erfa.pav2pv(
++ earth_pv = pav2pv(
+ earth_p.get_xyz(xyz_axis=-1).to_value(u.au),
+ earth_v.get_xyz(xyz_axis=-1).to_value(u.au/u.d))
+ return earth_pv, earth_heliocentric
+Index: astropy-4.1/astropy/coordinates/earth.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/earth.py
++++ astropy-4.1/astropy/coordinates/earth.py
+@@ -9,6 +9,8 @@ import urllib.error
+ import urllib.parse
+
+ import numpy as np
++import erfa
++
+ from astropy import units as u
+ from astropy import constants as consts
+ from astropy.units.quantity import QuantityInfoBase
+@@ -17,7 +19,7 @@ from .angles import Angle, Longitude, La
+ from .representation import CartesianRepresentation, CartesianDifferential
+ from .errors import UnknownSiteException
+ from astropy.utils import data
+-from astropy import _erfa as erfa
++
+
+ __all__ = ['EarthLocation']
+
+Index: astropy-4.1/astropy/coordinates/funcs.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/funcs.py
++++ astropy-4.1/astropy/coordinates/funcs.py
+@@ -12,10 +12,10 @@ import warnings
+ from collections.abc import Sequence
+
+ import numpy as np
++import erfa
+
+ from astropy import units as u
+ from astropy.constants import c
+-from astropy import _erfa as erfa
+ from astropy.io import ascii
+ from astropy.utils import isiterable, data
+ from .sky_coordinate import SkyCoord
+Index: astropy-4.1/astropy/coordinates/orbital_elements.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/orbital_elements.py
++++ astropy-4.1/astropy/coordinates/orbital_elements.py
+@@ -7,9 +7,9 @@ second edition, 1998, Willmann-Bell.
+
+ import numpy as np
+ from numpy.polynomial.polynomial import polyval
++import erfa
+
+ from astropy import units as u
+-from astropy import _erfa as erfa
+ from . import ICRS, SkyCoord, GeocentricTrueEcliptic
+ from .builtin_frames.utils import get_jd12
+
+Index: astropy-4.1/astropy/coordinates/representation.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/representation.py
++++ astropy-4.1/astropy/coordinates/representation.py
+@@ -13,10 +13,10 @@ import warnings
+
+ import numpy as np
+ import astropy.units as u
++from erfa import ufunc as erfa_ufunc
+
+ from .angles import Angle, Longitude, Latitude
+ from .distances import Distance
+-from astropy._erfa import ufunc as erfa_ufunc
+ from astropy.utils import ShapedLikeNDArray, classproperty
+ from astropy.utils.data_info import MixinInfo
+ from astropy.utils.exceptions import DuplicateRepresentationWarning
+Index: astropy-4.1/astropy/coordinates/sky_coordinate.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/sky_coordinate.py
++++ astropy-4.1/astropy/coordinates/sky_coordinate.py
+@@ -5,8 +5,8 @@ import contextlib
+ import operator
+
+ import numpy as np
++import erfa
+
+-from astropy import _erfa as erfa
+ from astropy.utils.compat.misc import override__dir__
+ from astropy import units as u
+ from astropy.constants import c as speed_of_light
+Index: astropy-4.1/astropy/coordinates/solar_system.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/solar_system.py
++++ astropy-4.1/astropy/coordinates/solar_system.py
+@@ -6,9 +6,10 @@ ephemerides from jplephem.
+
+ from urllib.parse import urlparse
+ from collections import OrderedDict
++import os.path
+
+ import numpy as np
+-import os.path
++import erfa
+
+ from .sky_coordinate import SkyCoord
+ from astropy.utils.data import download_file
+@@ -16,7 +17,6 @@ from astropy.utils.decorators import cla
+ from astropy.utils.state import ScienceState
+ from astropy.utils import indent
+ from astropy import units as u
+-from astropy import _erfa as erfa
+ from astropy.constants import c as speed_of_light
+ from .representation import CartesianRepresentation
+ from .orbital_elements import calc_moon
+Index: astropy-4.1/astropy/coordinates/tests/test_atc_replacements.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/tests/test_atc_replacements.py
++++ astropy-4.1/astropy/coordinates/tests/test_atc_replacements.py
+@@ -6,10 +6,10 @@
+ from itertools import product
+
+ import pytest
++import erfa
+
+ from astropy.tests.helper import assert_quantity_allclose as assert_allclose
+ from astropy.time import Time
+-from astropy import _erfa as erfa
+ from .utils import randomly_sample_sphere
+ from astropy.coordinates.builtin_frames.utils import get_jd12, atciqz, aticq
+ from astropy.coordinates import SphericalRepresentation
+Index: astropy-4.1/astropy/coordinates/tests/test_funcs.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/tests/test_funcs.py
++++ astropy-4.1/astropy/coordinates/tests/test_funcs.py
+@@ -10,10 +10,8 @@ import pytest
+ import numpy as np
+ from numpy import testing as npt
+
+-
+ from astropy import units as u
+ from astropy.time import Time
+-from astropy._erfa import ErfaWarning
+
+
+ def test_sun():
+Index: astropy-4.1/astropy/coordinates/tests/test_iau_fullstack.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/tests/test_iau_fullstack.py
++++ astropy-4.1/astropy/coordinates/tests/test_iau_fullstack.py
+@@ -6,6 +6,7 @@ import warnings
+ import pytest
+ import numpy as np
+ from numpy import testing as npt
++import erfa
+
+ from astropy import units as u
+ from astropy.time import Time
+@@ -14,7 +15,6 @@ from astropy.coordinates.builtin_frames.
+ from astropy.coordinates import EarthLocation
+ from astropy.coordinates import SkyCoord
+ from astropy.tests.helper import catch_warnings
+-from astropy import _erfa as erfa
+ from astropy.utils import iers
+ from .utils import randomly_sample_sphere
+
+Index: astropy-4.1/astropy/coordinates/tests/test_intermediate_transformations.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/tests/test_intermediate_transformations.py
++++ astropy-4.1/astropy/coordinates/tests/test_intermediate_transformations.py
+@@ -5,6 +5,7 @@
+
+ import pytest
+ import numpy as np
++import erfa
+
+ from astropy import units as u
+ from astropy.tests.helper import (assert_quantity_allclose as assert_allclose,
+@@ -16,9 +17,6 @@ from astropy.coordinates import (EarthLo
+ HCRS, HeliocentricMeanEcliptic, TEME)
+ from astropy.utils import iers
+
+-
+-from astropy._erfa import epv00
+-
+ from .utils import randomly_sample_sphere
+ from astropy.coordinates.builtin_frames.utils import get_jd12
+ from astropy.coordinates import solar_system_ephemeris
+@@ -449,7 +447,7 @@ def test_icrs_altaz_moonish(testframe):
+ right AltAz distance
+ """
+ # we use epv00 instead of get_sun because get_sun includes aberration
+- earth_pv_helio, earth_pv_bary = epv00(*get_jd12(testframe.obstime, 'tdb'))
++ earth_pv_helio, earth_pv_bary = erfa.epv00(*get_jd12(testframe.obstime, 'tdb'))
+ earth_icrs_xyz = earth_pv_bary[0]*u.au
+ moonoffset = [0, 0, MOONDIST.value]*MOONDIST.unit
+ moonish_icrs = ICRS(CartesianRepresentation(earth_icrs_xyz + moonoffset))
+Index: astropy-4.1/astropy/coordinates/tests/test_regression.py
+===================================================================
+--- astropy-4.1.orig/astropy/coordinates/tests/test_regression.py
++++ astropy-4.1/astropy/coordinates/tests/test_regression.py
+@@ -615,9 +615,9 @@ def test_regression_8276():
+
+
+ def test_regression_8615():
+- # note this is a "higher-level" symptom of the problem
+- # _erfa/tests/test_erfa:test_float32_input is testing for, but is kept here
+- # due to being a more practical version of the issue.
++ # note this is a "higher-level" symptom of the problem that a test now moved
++ # to pyerfa (erfa/tests/test_erfa:test_float32_input) is testing for, but we keep
++ # it here as well due to being a more practical version of the issue.
+
+ crf = CartesianRepresentation(np.array([3, 0, 4], dtype=float) * u.pc)
+ srf = SphericalRepresentation.from_cartesian(crf) # does not error in 8615
+Index: astropy-4.1/astropy/_erfa/core.py.templ
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/core.py.templ
++++ /dev/null
+@@ -1,230 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-
+-# "core.py" is auto-generated by erfa_generator.py from the template
+-# "core.py.templ". Do *not* edit "core.py" directly, instead edit
+-# "core.py.templ" and run erfa_generator.py from the source directory to
+-# update it.
+-
+-"""
+-Python wrappers for the ufunc wrappers of the ERFA library.
+-
+-..warning::
+- This is currently *not* part of the public Astropy API, and may change in
+- the future.
+-
+-The key idea is that any function can be called with inputs that are arrays,
+-and the ufuncs will automatically vectorize and call the ERFA functions for
+-each item using broadcasting rules for numpy. So the return values are always
+-numpy arrays of some sort.
+-
+-For ERFA functions that take/return vectors or matrices, the vector/matrix
+-dimension(s) are always the *last* dimension(s). For example, if you
+-want to give ten matrices (i.e., the ERFA input type is double[3][3]),
+-you would pass in a (10, 3, 3) numpy array. If the output of the ERFA
+-function is scalar, you'll get back a length-10 1D array.
+-(Note that the ufuncs take this into account using structured dtypes.)
+-
+-Note that the ufunc part of these functions are implemented in a separate
+-module (compiled as ``ufunc``), derived from the ``ufunc.c`` file.
+-"""
+-
+-import warnings
+-
+-import numpy
+-
+-# we import these exceptions from astropy locations instead of defining them
+-# in this file because otherwise there are circular dependencies
+-from astropy.utils.exceptions import ErfaError, ErfaWarning
+-from astropy.utils.misc import check_broadcast
+-
+-from . import ufunc
+-
+-__all__ = ['ErfaError', 'ErfaWarning',
+- {{ funcs|map(attribute='pyname')|surround("'","'")|join(", ") }},
+- {{ constants|map(attribute='name')|surround("'","'")|join(", ") }},
+- # TODO: delete the functions below when they can get auto-generated
+- 'version', 'version_major', 'version_minor', 'version_micro', 'sofa_version']
+-
+-
+-# <---------------------------------Error-handling---------------------------->
+-
+-
+-STATUS_CODES = {} # populated below before each function that returns an int
+-
+-# This is a hard-coded list of status codes that need to be remapped,
+-# such as to turn errors into warnings.
+-STATUS_CODES_REMAP = {
+- 'cal2jd': {-3: 3}
+-}
+-
+-
+-def check_errwarn(statcodes, func_name):
+- if not numpy.any(statcodes):
+- return
+- # Remap any errors into warnings in the STATUS_CODES_REMAP dict.
+- if func_name in STATUS_CODES_REMAP:
+- for before, after in STATUS_CODES_REMAP[func_name].items():
+- statcodes[statcodes == before] = after
+- STATUS_CODES[func_name][after] = STATUS_CODES[func_name][before]
+-
+- if numpy.any(statcodes<0):
+- # errors present - only report the errors.
+- if statcodes.shape:
+- statcodes = statcodes[statcodes<0]
+-
+- errcodes = numpy.unique(statcodes)
+-
+- errcounts = dict([(e, numpy.sum(statcodes==e)) for e in errcodes])
+-
+- elsemsg = STATUS_CODES[func_name].get('else', None)
+- if elsemsg is None:
+- errmsgs = dict([(e, STATUS_CODES[func_name].get(e, 'Return code ' + str(e))) for e in errcodes])
+- else:
+- errmsgs = dict([(e, STATUS_CODES[func_name].get(e, elsemsg)) for e in errcodes])
+-
+- emsg = ', '.join(['{0} of "{1}"'.format(errcounts[e], errmsgs[e]) for e in errcodes])
+- raise ErfaError('ERFA function "' + func_name + '" yielded ' + emsg)
+-
+- elif numpy.any(statcodes>0):
+- #only warnings present
+- if statcodes.shape:
+- statcodes = statcodes[statcodes>0]
+-
+- warncodes = numpy.unique(statcodes)
+-
+- warncounts = dict([(w, numpy.sum(statcodes==w)) for w in warncodes])
+-
+- elsemsg = STATUS_CODES[func_name].get('else', None)
+- if elsemsg is None:
+- warnmsgs = dict([(w, STATUS_CODES[func_name].get(w, 'Return code ' + str(w))) for w in warncodes])
+- else:
+- warnmsgs = dict([(w, STATUS_CODES[func_name].get(w, elsemsg)) for w in warncodes])
+-
+- wmsg = ', '.join(['{0} of "{1}"'.format(warncounts[w], warnmsgs[w]) for w in warncodes])
+- warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
+-
+-
+-# <------------------------structured dtype conversion------------------------>
+-
+-dt_bytes1 = numpy.dtype('S1')
+-dt_bytes12 = numpy.dtype('S12')
+-
+-# <--------------------------Actual ERFA-wrapping code------------------------>
+-
+-{% for constant in constants %}
+-{{ constant.name }} = {{ constant.value }}
+-"""{{ constant.doc|join(' ') }}"""
+-{%- endfor %}
+-
+-
+-{% for func in funcs -%}
+-def {{ func.pyname }}({{ func.args_by_inout('in|inout')|map(attribute='name')|join(', ') }}):
+- """
+- Wrapper for ERFA function ``{{ func.name }}``.
+-
+- Parameters
+- ----------
+- {%- for arg in func.args_by_inout('in|inout') %}
+- {{ arg.name }} : {{ arg.ctype }} array
+- {%- endfor %}
+-
+- Returns
+- -------
+- {%- for arg in func.args_by_inout('inout|out|ret') %}
+- {{ arg.name }} : {{ arg.ctype }} array
+- {%- endfor %}
+-
+- Notes
+- -----
+- The ERFA documentation is below. {% if func.args_by_inout('inout') -%}
+- Note that, unlike the erfa routine,
+- the python wrapper does not change {{ func.args_by_inout('inout')
+- | map(attribute='name')|join(', ') }} in-place.
+- {%- endif %}
+-
+-{{ func.doc }}
+- """
+-
+- {#-
+- # Call the ufunc. Note that we pass inout twice, once as input
+- # and once as output, so that changes are done in-place
+- #}
+- {{ func.python_call }}
+- {#-
+- # Check whether any warnings or errors occurred.
+- #}
+- {%- for arg in func.args_by_inout('stat') %}
+- check_errwarn({{ arg.name }}, '{{ func.pyname }}')
+- {%- endfor %}
+- {#-
+- # Any string outputs will be in structs; view them as their base type.
+- #}
+- {%- for arg in func.args_by_inout('out') -%}
+- {%- if 'char' in arg.ctype %}
+- {{ arg.name }} = {{ arg.name }}.view({{ arg.view_dtype }})
+- {%- endif %}
+- {%- endfor %}
+- {#-
+- # Return the output arguments (including the inplace ones)
+- #}
+- return {{ func.args_by_inout('inout|out|ret')|map(attribute='name')|join(', ') }}
+-
+-
+-{#
+- # Define the status codes that this function returns.
+- #}
+-{%- if func.args_by_inout('stat') -%}
+-{%- for stat in func.args_by_inout('stat') -%}
+-{%- if stat.doc_info.statuscodes -%}
+-STATUS_CODES['{{ func.pyname }}'] = {{ stat.doc_info.statuscodes|string }}
+-{% endif %}
+-{% endfor %}
+-{% endif -%}
+-{% endfor -%}
+-
+-
+-# TODO: delete the functions below when they can get auto-generated
+-# (current machinery doesn't support returning strings or non-status-codes)
+-def version():
+- """
+- Returns the package version
+- as defined in configure.ac
+- in string format
+- """
+- return "1.6.0"
+-
+-
+-def version_major():
+- """
+- Returns the package major version
+- as defined in configure.ac
+- as integer
+- """
+- return 1
+-
+-
+-def version_minor():
+- """
+- Returns the package minor version
+- as defined in configure.ac
+- as integer
+- """
+- return 6
+-
+-
+-def version_micro():
+- """
+- Returns the package micro version
+- as defined in configure.ac
+- as integer
+- """
+- return 0
+-
+-
+-def sofa_version():
+- """
+- Returns the corresponding SOFA version
+- as defined in configure.ac
+- in string format
+- """
+- return "20190722"
+Index: astropy-4.1/astropy/_erfa/erfa_additions.h
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/erfa_additions.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-#ifndef ERFAADDITIONSDEF
+-#define ERFAADDITIONSDEF
+-
+-/*
+-** - - - - - - - - - - - - - - - - -
+-** e r f a _ a d d i t i o n s . h
+-** - - - - - - - - - - - - - - - - -
+-**
+-** A few extra routines which are particularly handy for constructing
+-** pv vectors inside the coordinate transforms.
+-**
+-** MHvK proposed these to Catherine Hohenkerk for inclusion in SOFA
+-** on 2018-05-24, with the response suggesting this was reasonable and
+-** might thus be done.
+-*/
+-
+-/* Extra/PVMergeExtract */
+-void eraPav2pv(double p[3], double v[3], double pv[2][3]);
+-void eraPv2pav(double pv[2][3], double p[3], double v[3]);
+-
+-#endif
+Index: astropy-4.1/astropy/_erfa/erfa_generator.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/erfa_generator.py
++++ /dev/null
+@@ -1,699 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-"""
+-This module's main purpose is to act as a script to create new versions
+-of ufunc.c when ERFA is updated (or this generator is enhanced).
+-
+-`Jinja2 `_ must be installed for this
+-module/script to function.
+-
+-Note that this does *not* currently automate the process of creating structs
+-or dtypes for those structs. They should be added manually in the template file.
+-"""
+-
+-import re
+-import os.path
+-from collections import OrderedDict
+-
+-DEFAULT_ERFA_LOC = os.path.join(os.path.split(__file__)[0],
+- '../../cextern/erfa')
+-DEFAULT_TEMPLATE_LOC = os.path.split(__file__)[0]
+-
+-NDIMS_REX = re.compile(re.escape("numpy.dtype([('fi0', '.*', <(.*)>)])").replace(r'\.\*', '.*').replace(r'\<', '(').replace(r'\>', ')'))
+-
+-
+-class FunctionDoc:
+-
+- def __init__(self, doc):
+- self.doc = doc.replace("**", " ").replace("/*\n", "").replace("*/", "")
+- self.__input = None
+- self.__output = None
+- self.__ret_info = None
+-
+- def _get_arg_doc_list(self, doc_lines):
+- """Parse input/output doc section lines, getting arguments from them.
+-
+- Ensure all elements of eraASTROM and eraLDBODY are left out, as those
+- are not input or output arguments themselves. Also remove the nb
+- argument in from of eraLDBODY, as we infer nb from the python array.
+- """
+- doc_list = []
+- skip = []
+- for d in doc_lines:
+- arg_doc = ArgumentDoc(d)
+- if arg_doc.name is not None:
+- if skip:
+- if skip[0] == arg_doc.name:
+- skip.pop(0)
+- continue
+- else:
+- raise RuntimeError("We whould be skipping {} "
+- "but {} encountered."
+- .format(skip[0], arg_doc.name))
+-
+- if arg_doc.type.startswith('eraLDBODY'):
+- # Special-case LDBODY: for those, the previous argument
+- # is always the number of bodies, but we don't need it
+- # as an input argument for the ufunc since we're going
+- # to determine this from the array itself. Also skip
+- # the description of its contents; those are not arguments.
+- doc_list.pop()
+- skip = ['bm', 'dl', 'pv']
+- elif arg_doc.type.startswith('eraASTROM'):
+- # Special-case ASTROM: need to skip the description
+- # of its contents; those are not arguments.
+- skip = ['pmt', 'eb', 'eh', 'em', 'v', 'bm1',
+- 'bpn', 'along', 'xpl', 'ypl', 'sphi',
+- 'cphi', 'diurab', 'eral', 'refa', 'refb']
+-
+- doc_list.append(arg_doc)
+-
+- return doc_list
+-
+- @property
+- def input(self):
+- if self.__input is None:
+- self.__input = []
+- for regex in ("Given([^\n]*):.*?\n(.+?) \n",
+- "Given and returned([^\n]*):\n(.+?) \n"):
+- result = re.search(regex, self.doc, re.DOTALL)
+- if result is not None:
+- doc_lines = result.group(2).split("\n")
+- self.__input += self._get_arg_doc_list(doc_lines)
+-
+- return self.__input
+-
+- @property
+- def output(self):
+- if self.__output is None:
+- self.__output = []
+- for regex in ("Given and returned([^\n]*):\n(.+?) \n",
+- "Returned([^\n]*):.*?\n(.+?) \n"):
+- result = re.search(regex, self.doc, re.DOTALL)
+- if result is not None:
+- doc_lines = result.group(2).split("\n")
+- self.__output += self._get_arg_doc_list(doc_lines)
+-
+- return self.__output
+-
+- @property
+- def ret_info(self):
+- if self.__ret_info is None:
+- ret_info = []
+- result = re.search("Returned \\(function value\\)([^\n]*):\n(.+?) \n", self.doc, re.DOTALL)
+- if result is not None:
+- ret_info.append(ReturnDoc(result.group(2)))
+-
+- if len(ret_info) == 0:
+- self.__ret_info = ''
+- elif len(ret_info) == 1:
+- self.__ret_info = ret_info[0]
+- else:
+- raise ValueError("Multiple C return sections found in this doc:\n" + self.doc)
+-
+- return self.__ret_info
+-
+- def __repr__(self):
+- return self.doc.replace(" \n", "\n")
+-
+-
+-class ArgumentDoc:
+-
+- def __init__(self, doc):
+- match = re.search("^ +([^ ]+)[ ]+([^ ]+)[ ]+(.+)", doc)
+- if match is not None:
+- self.name = match.group(1)
+- if self.name.startswith('*'): # easier than getting the regex to behave...
+- self.name = self.name.replace('*', '')
+- self.type = match.group(2)
+- self.doc = match.group(3)
+- else:
+- self.name = None
+- self.type = None
+- self.doc = None
+-
+- def __repr__(self):
+- return f" {self.name:15} {self.type:15} {self.doc}"
+-
+-
+-class Variable:
+- """Properties shared by Argument and Return."""
+- @property
+- def npy_type(self):
+- """Predefined type used by numpy ufuncs to indicate a given ctype.
+-
+- Eg., NPY_DOUBLE for double.
+- """
+- return "NPY_" + self.ctype.upper()
+-
+- @property
+- def dtype(self):
+- """Name of dtype corresponding to the ctype.
+-
+- Specifically,
+- double : dt_double
+- int : dt_int
+- double[3]: dt_vector
+- double[2][3] : dt_pv
+- double[2] : dt_pvdpv
+- double[3][3] : dt_matrix
+- int[4] : dt_ymdf | dt_hmsf | dt_dmsf, depding on name
+- eraASTROM: dt_eraASTROM
+- eraLDBODY: dt_eraLDBODY
+- char : dt_sign
+- char[] : dt_type
+-
+- The corresponding dtypes are defined in ufunc.c, where they are
+- used for the loop definitions. In core.py, they are also used
+- to view-cast regular arrays to these structured dtypes.
+- """
+- if self.ctype == 'const char':
+- return 'dt_type'
+- elif self.ctype == 'char':
+- return 'dt_sign'
+- elif self.ctype == 'int' and self.shape == (4,):
+- return 'dt_' + self.name[1:]
+- elif self.ctype == 'double' and self.shape == (3,):
+- return 'dt_double'
+- elif self.ctype == 'double' and self.shape == (2, 3):
+- return 'dt_pv'
+- elif self.ctype == 'double' and self.shape == (2,):
+- return 'dt_pvdpv'
+- elif self.ctype == 'double' and self.shape == (3, 3):
+- return 'dt_double'
+- elif not self.shape:
+- return 'dt_' + self.ctype
+- else:
+- raise ValueError("ctype {} with shape {} not recognized."
+- .format(self.ctype, self.shape))
+-
+- @property
+- def view_dtype(self):
+- """Name of dtype corresponding to the ctype for viewing back as array.
+-
+- E.g., dt_double for double, dt_double33 for double[3][3].
+-
+- The types are defined in core.py, where they are used for view-casts
+- of structured results as regular arrays.
+- """
+- if self.ctype == 'const char':
+- return 'dt_bytes12'
+- elif self.ctype == 'char':
+- return 'dt_bytes1'
+- else:
+- raise ValueError('Only char ctype should need view back!')
+-
+- @property
+- def ndim(self):
+- return len(self.shape)
+-
+- @property
+- def size(self):
+- size = 1
+- for s in self.shape:
+- size *= s
+- return size
+-
+- @property
+- def cshape(self):
+- return ''.join([f'[{s}]' for s in self.shape])
+-
+- @property
+- def signature_shape(self):
+- if self.ctype == 'eraLDBODY':
+- return '(n)'
+- elif self.ctype == 'double' and self.shape == (3,):
+- return '(3)'
+- elif self.ctype == 'double' and self.shape == (3, 3):
+- return '(3, 3)'
+- else:
+- return '()'
+-
+-
+-class Argument(Variable):
+-
+- def __init__(self, definition, doc):
+- self.definition = definition
+- self.doc = doc
+- self.__inout_state = None
+- self.ctype, ptr_name_arr = definition.strip().rsplit(" ", 1)
+- if "*" == ptr_name_arr[0]:
+- self.is_ptr = True
+- name_arr = ptr_name_arr[1:]
+- else:
+- self.is_ptr = False
+- name_arr = ptr_name_arr
+- if "[]" in ptr_name_arr:
+- self.is_ptr = True
+- name_arr = name_arr[:-2]
+- if "[" in name_arr:
+- self.name, arr = name_arr.split("[", 1)
+- self.shape = tuple([int(size) for size in arr[:-1].split("][")])
+- else:
+- self.name = name_arr
+- self.shape = ()
+-
+- @property
+- def inout_state(self):
+- if self.__inout_state is None:
+- self.__inout_state = ''
+- for i in self.doc.input:
+- if self.name in i.name.split(','):
+- self.__inout_state = 'in'
+- for o in self.doc.output:
+- if self.name in o.name.split(','):
+- if self.__inout_state == 'in':
+- self.__inout_state = 'inout'
+- else:
+- self.__inout_state = 'out'
+- return self.__inout_state
+-
+- @property
+- def name_for_call(self):
+- """How the argument should be used in the call to the ERFA function.
+-
+- This takes care of ensuring that inputs are passed by value,
+- as well as adding back the number of bodies for any LDBODY argument.
+- The latter presumes that in the ufunc inner loops, that number is
+- called 'nb'.
+- """
+- if self.ctype == 'eraLDBODY':
+- assert self.name == 'b'
+- return 'nb, _' + self.name
+- elif self.is_ptr:
+- return '_'+self.name
+- else:
+- return '*_'+self.name
+-
+- def __repr__(self):
+- return f"Argument('{self.definition}', name='{self.name}', ctype='{self.ctype}', inout_state='{self.inout_state}')"
+-
+-
+-class ReturnDoc:
+-
+- def __init__(self, doc):
+- self.doc = doc
+-
+- self.infoline = doc.split('\n')[0].strip()
+- self.type = self.infoline.split()[0]
+- self.descr = self.infoline.split()[1]
+-
+- if self.descr.startswith('status'):
+- self.statuscodes = statuscodes = {}
+-
+- code = None
+- for line in doc[doc.index(':')+1:].split('\n'):
+- ls = line.strip()
+- if ls != '':
+- if ' = ' in ls:
+- code, msg = ls.split(' = ')
+- if code != 'else':
+- code = int(code)
+- statuscodes[code] = msg
+- elif code is not None:
+- statuscodes[code] += ls
+- else:
+- self.statuscodes = None
+-
+- def __repr__(self):
+- return f"Return value, type={self.type:15}, {self.descr}, {self.doc}"
+-
+-
+-class Return(Variable):
+-
+- def __init__(self, ctype, doc):
+- self.name = 'c_retval'
+- self.inout_state = 'stat' if ctype == 'int' else 'ret'
+- self.ctype = ctype
+- self.shape = ()
+- self.doc = doc
+-
+- def __repr__(self):
+- return f"Return(name='{self.name}', ctype='{self.ctype}', inout_state='{self.inout_state}')"
+-
+- @property
+- def doc_info(self):
+- return self.doc.ret_info
+-
+-
+-class Function:
+- """
+- A class representing a C function.
+-
+- Parameters
+- ----------
+- name : str
+- The name of the function
+- source_path : str
+- Either a directory, which means look for the function in a
+- stand-alone file (like for the standard ERFA distribution), or a
+- file, which means look for the function in that file (as for the
+- astropy-packaged single-file erfa.c).
+- match_line : str, optional
+- If given, searching of the source file will skip until it finds
+- a line matching this string, and start from there.
+- """
+-
+- def __init__(self, name, source_path, match_line=None):
+- self.name = name
+- self.pyname = name.split('era')[-1].lower()
+- self.filename = self.pyname+".c"
+- if os.path.isdir(source_path):
+- self.filepath = os.path.join(os.path.normpath(source_path), self.filename)
+- else:
+- self.filepath = source_path
+-
+- with open(self.filepath) as f:
+- if match_line:
+- line = f.readline()
+- while line != '':
+- if line.startswith(match_line):
+- filecontents = '\n' + line + f.read()
+- break
+- line = f.readline()
+- else:
+- msg = ('Could not find the match_line "{0}" in '
+- 'the source file "{1}"')
+- raise ValueError(msg.format(match_line, self.filepath))
+- else:
+- filecontents = f.read()
+-
+- pattern = fr"\n([^\n]+{name} ?\([^)]+\)).+?(/\*.+?\*/)"
+- p = re.compile(pattern, flags=re.DOTALL | re.MULTILINE)
+-
+- search = p.search(filecontents)
+- self.cfunc = " ".join(search.group(1).split())
+- self.doc = FunctionDoc(search.group(2))
+-
+- self.args = []
+- for arg in re.search(r"\(([^)]+)\)", self.cfunc).group(1).split(', '):
+- self.args.append(Argument(arg, self.doc))
+- self.ret = re.search(f"^(.*){name}", self.cfunc).group(1).strip()
+- if self.ret != 'void':
+- self.args.append(Return(self.ret, self.doc))
+-
+- def args_by_inout(self, inout_filter, prop=None, join=None):
+- """
+- Gives all of the arguments and/or returned values, depending on whether
+- they are inputs, outputs, etc.
+-
+- The value for `inout_filter` should be a string containing anything
+- that arguments' `inout_state` attribute produces. Currently, that can be:
+-
+- * "in" : input
+- * "out" : output
+- * "inout" : something that's could be input or output (e.g. a struct)
+- * "ret" : the return value of the C function
+- * "stat" : the return value of the C function if it is a status code
+-
+- It can also be a "|"-separated string giving inout states to OR
+- together.
+- """
+- result = []
+- for arg in self.args:
+- if arg.inout_state in inout_filter.split('|'):
+- if prop is None:
+- result.append(arg)
+- else:
+- result.append(getattr(arg, prop))
+- if join is not None:
+- return join.join(result)
+- else:
+- return result
+-
+- @property
+- def user_dtype(self):
+- """The non-standard dtype, if any, needed by this function's ufunc.
+-
+- This would be any structured array for any input or output, but
+- we give preference to LDBODY, since that also decides that the ufunc
+- should be a generalized ufunc.
+- """
+- user_dtype = None
+- for arg in self.args_by_inout('in|inout|out'):
+- if arg.ctype == 'eraLDBODY':
+- return arg.dtype
+- elif user_dtype is None and arg.dtype not in ('dt_double',
+- 'dt_int'):
+- user_dtype = arg.dtype
+-
+- return user_dtype
+-
+- @property
+- def signature(self):
+- """Possible signature, if this function should be a gufunc."""
+- if all(arg.signature_shape == '()'
+- for arg in self.args_by_inout('in|inout|out')):
+- return None
+-
+- return '->'.join(
+- [','.join([arg.signature_shape for arg in args])
+- for args in (self.args_by_inout('in|inout'),
+- self.args_by_inout('inout|out|ret|stat'))])
+-
+- @property
+- def python_call(self):
+- outnames = [arg.name for arg in self.args_by_inout('inout|out|stat|ret')]
+- argnames = [arg.name for arg in self.args_by_inout('in|inout')]
+- return '{out} = {func}({args})'.format(out=', '.join(outnames),
+- func='ufunc.' + self.pyname,
+- args=', '.join(argnames))
+-
+- def __repr__(self):
+- return f"Function(name='{self.name}', pyname='{self.pyname}', filename='{self.filename}', filepath='{self.filepath}')"
+-
+-
+-class Constant:
+-
+- def __init__(self, name, value, doc):
+- self.name = name.replace("ERFA_", "")
+- self.value = value.replace("ERFA_", "")
+- self.doc = doc
+-
+-
+-class ExtraFunction(Function):
+- """
+- An "extra" function - e.g. one not following the SOFA/ERFA standard format.
+-
+- Parameters
+- ----------
+- cname : str
+- The name of the function in C
+- prototype : str
+- The prototype for the function (usually derived from the header)
+- pathfordoc : str
+- The path to a file that contains the prototype, with the documentation
+- as a multiline string *before* it.
+- """
+-
+- def __init__(self, cname, prototype, pathfordoc):
+- self.name = cname
+- self.pyname = cname.split('era')[-1].lower()
+- self.filepath, self.filename = os.path.split(pathfordoc)
+-
+- self.prototype = prototype.strip()
+- if prototype.endswith('{') or prototype.endswith(';'):
+- self.prototype = prototype[:-1].strip()
+-
+- incomment = False
+- lastcomment = None
+- with open(pathfordoc, 'r') as f:
+- for l in f:
+- if incomment:
+- if l.lstrip().startswith('*/'):
+- incomment = False
+- lastcomment = ''.join(lastcomment)
+- else:
+- if l.startswith('**'):
+- l = l[2:]
+- lastcomment.append(l)
+- else:
+- if l.lstrip().startswith('/*'):
+- incomment = True
+- lastcomment = []
+- if l.startswith(self.prototype):
+- self.doc = lastcomment
+- break
+- else:
+- raise ValueError('Did not find prototype {} in file '
+- '{}'.format(self.prototype, pathfordoc))
+-
+- self.args = []
+- argset = re.search(fr"{self.name}\(([^)]+)?\)",
+- self.prototype).group(1)
+- if argset is not None:
+- for arg in argset.split(', '):
+- self.args.append(Argument(arg, self.doc))
+- self.ret = re.match(f"^(.*){self.name}",
+- self.prototype).group(1).strip()
+- if self.ret != 'void':
+- self.args.append(Return(self.ret, self.doc))
+-
+- def __repr__(self):
+- r = super().__repr__()
+- if r.startswith('Function'):
+- r = 'Extra' + r
+- return r
+-
+-
+-def main(srcdir=DEFAULT_ERFA_LOC, outfn='core.py', ufuncfn='ufunc.c',
+- templateloc=DEFAULT_TEMPLATE_LOC, extra='erfa_additions.h',
+- verbose=True):
+- from jinja2 import Environment, FileSystemLoader
+-
+- if verbose:
+- print_ = lambda *args, **kwargs: print(*args, **kwargs)
+- else:
+- print_ = lambda *args, **kwargs: None
+-
+- # Prepare the jinja2 templating environment
+- env = Environment(loader=FileSystemLoader(templateloc))
+-
+- def prefix(a_list, pre):
+- return [pre+f'{an_element}' for an_element in a_list]
+-
+- def postfix(a_list, post):
+- return [f'{an_element}'+post for an_element in a_list]
+-
+- def surround(a_list, pre, post):
+- return [pre+f'{an_element}'+post for an_element in a_list]
+- env.filters['prefix'] = prefix
+- env.filters['postfix'] = postfix
+- env.filters['surround'] = surround
+-
+- erfa_c_in = env.get_template(ufuncfn + '.templ')
+- erfa_py_in = env.get_template(outfn + '.templ')
+-
+- # Extract all the ERFA function names from erfa.h
+- if os.path.isdir(srcdir):
+- erfahfn = os.path.join(srcdir, 'erfa.h')
+- multifilserc = True
+- else:
+- erfahfn = os.path.join(os.path.split(srcdir)[0], 'erfa.h')
+- multifilserc = False
+-
+- with open(erfahfn, "r") as f:
+- erfa_h = f.read()
+- print_("read erfa header")
+- if extra:
+- with open(os.path.join(templateloc or '.', extra), "r") as f:
+- erfa_h += f.read()
+- print_("read extra header")
+-
+- funcs = OrderedDict()
+- section_subsection_functions = re.findall(
+- r'/\* (\w*)/(\w*) \*/\n(.*?)\n\n', erfa_h,
+- flags=re.DOTALL | re.MULTILINE)
+- for section, subsection, functions in section_subsection_functions:
+- print_(f"{section}.{subsection}")
+- # Right now, we compile everything, but one could be more selective.
+- # In particular, at the time of writing (2018-06-11), what was
+- # actually require for astropy was not quite everything, but:
+- # ((section == 'Extra')
+- # or (section == "Astronomy")
+- # or (subsection == "AngleOps")
+- # or (subsection == "SphericalCartesian")
+- # or (subsection == "MatrixVectorProducts")
+- # or (subsection == 'VectorOps'))
+- if True:
+-
+- func_names = re.findall(r' (\w+)\(.*?\);', functions,
+- flags=re.DOTALL)
+- for name in func_names:
+- print_(f"{section}.{subsection}.{name}...")
+- if multifilserc:
+- # easy because it just looks in the file itself
+- cdir = (srcdir if section != 'Extra' else
+- templateloc or '.')
+- funcs[name] = Function(name, cdir)
+- else:
+- # Have to tell it to look for a declaration matching
+- # the start of the header declaration, otherwise it
+- # might find a *call* of the function instead of the
+- # definition
+- for line in functions.split(r'\n'):
+- if name in line:
+- # [:-1] is to remove trailing semicolon, and
+- # splitting on '(' is because the header and
+- # C files don't necessarily have to match
+- # argument names and line-breaking or
+- # whitespace
+- match_line = line[:-1].split('(')[0]
+- funcs[name] = Function(name, cdir, match_line)
+- break
+- else:
+- raise ValueError("A name for a C file wasn't "
+- "found in the string that "
+- "spawned it. This should be "
+- "impossible!")
+-
+- funcs = funcs.values()
+-
+- # Extract all the ERFA constants from erfam.h
+- erfamhfn = os.path.join(srcdir, 'erfam.h')
+- with open(erfamhfn, 'r') as f:
+- erfa_m_h = f.read()
+- constants = []
+- for chunk in erfa_m_h.split("\n\n"):
+- result = re.findall(r"#define (ERFA_\w+?) (.+?)$", chunk,
+- flags=re.DOTALL | re.MULTILINE)
+- if result:
+- doc = re.findall(r"/\* (.+?) \*/\n", chunk, flags=re.DOTALL)
+- for (name, value) in result:
+- constants.append(Constant(name, value, doc))
+-
+- # TODO: re-enable this when const char* return values and
+- # non-status code integer rets are possible
+- # #Add in any "extra" functions from erfaextra.h
+- # erfaextrahfn = os.path.join(srcdir, 'erfaextra.h')
+- # with open(erfaextrahfn, 'r') as f:
+- # for l in f:
+- # ls = l.strip()
+- # match = re.match('.* (era.*)\(', ls)
+- # if match:
+- # print_("Extra: {0} ...".format(match.group(1)))
+- # funcs.append(ExtraFunction(match.group(1), ls, erfaextrahfn))
+-
+- print_("Rendering template")
+- erfa_c = erfa_c_in.render(funcs=funcs)
+- erfa_py = erfa_py_in.render(funcs=funcs, constants=constants)
+-
+- if outfn is not None:
+- print_("Saving to", outfn, 'and', ufuncfn)
+- with open(os.path.join(templateloc, outfn), "w") as f:
+- f.write(erfa_py)
+- with open(os.path.join(templateloc, ufuncfn), "w") as f:
+- f.write(erfa_c)
+-
+- print_("Done!")
+-
+- return erfa_c, erfa_py, funcs
+-
+-
+-if __name__ == '__main__':
+- from argparse import ArgumentParser
+-
+- ap = ArgumentParser()
+- ap.add_argument('srcdir', default=DEFAULT_ERFA_LOC, nargs='?',
+- help='Directory where the ERFA c and header files '
+- 'can be found or to a single erfa.c file '
+- '(which must be in the same directory as '
+- 'erfa.h). Defaults to the builtin astropy '
+- 'erfa: "{}"'.format(DEFAULT_ERFA_LOC))
+- ap.add_argument('-o', '--output', default='core.py',
+- help='The output filename for the pure-python output.')
+- ap.add_argument('-u', '--ufunc', default='ufunc.c',
+- help='The output filename for the ufunc .c output')
+- ap.add_argument('-t', '--template-loc',
+- default=DEFAULT_TEMPLATE_LOC,
+- help='the location where the "core.py.templ" and '
+- '"ufunc.c.templ templates can be found.')
+- ap.add_argument('-x', '--extra',
+- default='erfa_additions.h',
+- help='header file for any extra files in the template '
+- 'location that should be included.')
+- ap.add_argument('-q', '--quiet', action='store_false', dest='verbose',
+- help='Suppress output normally printed to stdout.')
+-
+- args = ap.parse_args()
+- main(args.srcdir, args.output, args.ufunc, args.template_loc,
+- args.extra)
+Index: astropy-4.1/astropy/_erfa/helpers.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/helpers.py
++++ /dev/null
+@@ -1,216 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-"""
+-Helpers to interact with the ERFA library, in particular for leap seconds.
+-"""
+-from datetime import datetime, timedelta
+-from warnings import warn
+-
+-import numpy as np
+-
+-from astropy.utils.decorators import classproperty
+-from astropy.utils.exceptions import ErfaWarning
+-
+-from .ufunc import get_leap_seconds, set_leap_seconds, dt_eraLEAPSECOND
+-
+-
+-class leap_seconds:
+- """Leap second management.
+-
+- This singleton class allows access to ERFA's leap second table,
+- using the methods 'get', 'set', and 'update'.
+-
+- One can also check expiration with 'expires' and 'expired'.
+-
+- Note that usage of the class is similar to a ``ScienceState`` class,
+- but it cannot be used as a context manager.
+- """
+- _expires = None
+- """Explicit expiration date inferred from leap-second table."""
+- _expiration_days = 180
+- """Number of days beyond last leap second at which table expires."""
+-
+- def __init__(self):
+- raise RuntimeError("This class is a singleton. Do not instantiate.")
+-
+- @classmethod
+- def get(cls):
+- """Get the current leap-second table used internally."""
+- return get_leap_seconds()
+-
+- @classmethod
+- def validate(cls, table):
+- """Validate a leap-second table.
+-
+- Parameters
+- ----------
+- table : array_like
+- Must have 'year', 'month', and 'tai_utc' entries. If a 'day'
+- entry is present, it will be checked that it is always 1.
+- If ``table`` has an 'expires' attribute, it will be interpreted
+- as an expiration date.
+-
+- Returns
+- -------
+- array : `~numpy.ndarray`
+- Structures array with 'year', 'month', 'tai_utc'.
+- expires: `~datetime.datetime` or None
+- Possible expiration date inferred from the table. `None` if not
+- present or if not a `~datetime.datetime` or `~astropy.time.Time`
+- instance and not parsable as a 'dd month yyyy' string.
+-
+- Raises
+- ------
+- ValueError
+- If the leap seconds in the table are not on the 1st of January or
+- July, or if the sorted TAI-UTC do not increase in increments of 1.
+- """
+- try:
+- day = table['day']
+- except Exception:
+- day = 1
+-
+- expires = getattr(table, 'expires', None)
+- if expires is not None and not isinstance(expires, datetime):
+- # Maybe astropy Time? Cannot go via strftime, since that
+- # might need leap-seconds. If not, try standard string
+- # format from leap_seconds.dat and leap_seconds.list
+- isot = getattr(expires, 'isot', None)
+- try:
+- if isot is not None:
+- expires = datetime.strptime(isot.partition('T')[0],
+- '%Y-%m-%d')
+- else:
+- expires = datetime.strptime(expires, '%d %B %Y')
+-
+- except Exception as exc:
+- warn(f"ignoring non-datetime expiration {expires}; "
+- f"parsing it raised {exc!r}", ErfaWarning)
+- expires = None
+-
+- # Take care of astropy Table.
+- if hasattr(table, '__array__'):
+- table = table.__array__()[list(dt_eraLEAPSECOND.names)]
+-
+- table = np.array(table, dtype=dt_eraLEAPSECOND, copy=False,
+- ndmin=1)
+-
+- # Simple sanity checks.
+- if table.ndim > 1:
+- raise ValueError("can only pass in one-dimensional tables.")
+-
+- if not np.all(((day == 1) &
+- (table['month'] == 1) | (table['month'] == 7)) |
+- (table['year'] < 1972)):
+- raise ValueError("leap seconds inferred that are not on "
+- "1st of January or 1st of July.")
+-
+- if np.any((table['year'][:-1] > 1970) &
+- (np.diff(table['tai_utc']) != 1)):
+- raise ValueError("jump in TAI-UTC by something else than one.")
+-
+- return table, expires
+-
+- @classmethod
+- def set(cls, table=None):
+- """Set the ERFA leap second table.
+-
+- Note that it is generally safer to update the leap-second table than
+- to set it directly, since most tables do not have the pre-1970 changes
+- in TAI-UTC that are part of the built-in ERFA table.
+-
+- Parameters
+- ----------
+- table : array_like or `None`
+- Leap-second table that should at least hold columns of 'year',
+- 'month', and 'tai_utc'. Only simple validation is done before it
+- is being used, so care need to be taken that entries are correct.
+- If `None`, reset the ERFA table to its built-in values.
+-
+- Raises
+- ------
+- ValueError
+- If the leap seconds in the table are not on the 1st of January or
+- July, or if the sorted TAI-UTC do not increase in increments of 1.
+- """
+- if table is None:
+- expires = None
+- else:
+- table, expires = cls.validate(table)
+-
+- set_leap_seconds(table)
+- cls._expires = expires
+-
+- @classproperty
+- def expires(cls):
+- """The expiration date of the current ERFA table.
+-
+- This is either a date inferred from the last table used to update or
+- set the leap-second array, or a number of days beyond the last leap
+- second.
+- """
+- if cls._expires is None:
+- last = cls.get()[-1]
+- return (datetime(last['year'], last['month'], 1) +
+- timedelta(cls._expiration_days))
+- else:
+- return cls._expires
+-
+- @classproperty
+- def expired(cls):
+- """Whether the leap second table is valid beyond the present."""
+- return cls.expires < datetime.now()
+-
+- @classmethod
+- def update(cls, table):
+- """Add any leap seconds not already present to the ERFA table.
+-
+- This method matches leap seconds with those present in the ERFA table,
+- and extends the latter as necessary.
+-
+- If the ERFA leap seconds file was corrupted, it will be reset.
+-
+- If the table is corrupted, the ERFA file will be unchanged.
+-
+- Parameters
+- ----------
+- table : array_like or `~astropy.utils.iers.LeapSeconds`
+- Array or table with TAI-UTC from leap seconds. Should have
+- 'year', 'month', and 'tai_utc' columns.
+-
+- Returns
+- -------
+- n_update : int
+- Number of items updated.
+-
+- Raises
+- ------
+- ValueError
+- If the leap seconds in the table are not on the 1st of January or
+- July, or if the sorted TAI-UTC do not increase in increments of 1.
+- """
+- table, expires = cls.validate(table)
+-
+- # Get erfa table and check it is OK; if not, reset it.
+- try:
+- erfa_ls, _ = cls.validate(cls.get())
+- except Exception:
+- cls.set()
+- erfa_ls = cls.get()
+-
+- # Create the combined array and use it (validating the combination).
+- ls = np.union1d(erfa_ls, table)
+- cls.set(ls)
+-
+- # If the update table has an expiration beyond that inferred from
+- # the new leap second second array, use it (but, now that the new
+- # array is set, do not allow exceptions due to misformed expires).
+- try:
+- if expires is not None and expires > cls.expires:
+- cls._expires = expires
+-
+- except Exception as exc:
+- warn("table 'expires' attribute ignored as comparing it "
+- "with a datetime raised an error:\n" + str(exc),
+- ErfaWarning)
+-
+- return len(ls) - len(erfa_ls)
+Index: astropy-4.1/astropy/_erfa/__init__.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/__init__.py
++++ astropy-4.1/astropy/_erfa/__init__.py
+@@ -1,6 +1,16 @@
+ # Licensed under a 3-clause BSD style license - see LICENSE.rst
++import warnings
+
+-from .core import *
+-from .ufunc import (dt_eraASTROM, dt_eraLDBODY, dt_eraLEAPSECOND, dt_pv,
+- dt_sign, dt_type, dt_ymdf, dt_hmsf, dt_dmsf)
+-from .helpers import leap_seconds
++from erfa import core, ufunc, helpers # noqa
++from erfa.core import * # noqa
++from erfa.ufunc import (dt_eraASTROM, dt_eraLDBODY, dt_eraLEAPSECOND, dt_pv, # noqa
++ dt_sign, dt_type, dt_ymdf, dt_hmsf, dt_dmsf)
++from erfa.helpers import leap_seconds # noqa
++
++from astropy.utils.exceptions import AstropyDeprecationWarning
++
++
++warnings.warn('The private astropy._erfa module has been made into its '
++ 'own package, pyerfa, which is a dependency of '
++ 'astropy and can be imported directly using "import erfa"',
++ AstropyDeprecationWarning)
+Index: astropy-4.1/astropy/_erfa/pav2pv.c
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/pav2pv.c
++++ /dev/null
+@@ -1,30 +0,0 @@
+-#include "erfa.h"
+-
+-void eraPav2pv(double p[3], double v[3], double pv[2][3])
+-/*
+-** - - - - - - - - - -
+-** e r a P a v 2 p v
+-** - - - - - - - - - -
+-**
+-** Extend a p-vector to a pv-vector by appending a zero velocity.
+-**
+-** Given:
+-** p double[3] p-vector
+-** v double[3] v-vector
+-**
+-** Returned:
+-** pv double[2][3] pv-vector
+-**
+-** Called:
+-** eraCp copy p-vector
+-**
+-** Copyright (C) 2013-2017, NumFOCUS Foundation.
+-** Derived, with permission, from the SOFA library. See notes at end of file.
+-*/
+-{
+- eraCp(p, pv[0]);
+- eraCp(v, pv[1]);
+-
+- return;
+-
+-}
+Index: astropy-4.1/astropy/_erfa/pv2pav.c
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/pv2pav.c
++++ /dev/null
+@@ -1,30 +0,0 @@
+-#include "erfa.h"
+-
+-void eraPv2pav(double pv[2][3], double p[3], double v[3])
+-/*
+-** - - - - - - - - -
+-** e r a P v 2 p a v
+-** - - - - - - - - -
+-**
+-** Extend a p-vector to a pv-vector by appending a zero velocity.
+-**
+-** Given:
+-** pv double[2][3] pv-vector
+-**
+-** Returned:
+-** p double[3] p-vector
+-** v double[3] v-vector
+-**
+-** Called:
+-** eraCp copy p-vector
+-**
+-** Copyright (C) 2013-2017, NumFOCUS Foundation.
+-** Derived, with permission, from the SOFA library. See notes at end of file.
+-*/
+-{
+- eraCp(pv[0], p);
+- eraCp(pv[1], v);
+-
+- return;
+-
+-}
+Index: astropy-4.1/astropy/_erfa/setup_package.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/setup_package.py
++++ /dev/null
+@@ -1,72 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-
+-import os
+-import glob
+-
+-from distutils.extension import Extension
+-from distutils.dep_util import newer
+-
+-import numpy
+-from extension_helpers import import_file
+-
+-ERFAPKGDIR = os.path.relpath(os.path.dirname(__file__))
+-
+-ERFA_SRC = os.path.abspath(os.path.join(ERFAPKGDIR, '..', '..',
+- 'cextern', 'erfa'))
+-
+-SRC_FILES = glob.glob(os.path.join(ERFA_SRC, '*'))
+-SRC_FILES += [os.path.join(ERFAPKGDIR, filename)
+- for filename in ['pav2pv.c', 'pv2pav.c', 'erfa_additions.h',
+- 'ufunc.c.templ', 'core.py.templ',
+- 'erfa_generator.py']]
+-
+-GEN_FILES = [os.path.join(ERFAPKGDIR, 'core.py'),
+- os.path.join(ERFAPKGDIR, 'ufunc.c')]
+-
+-
+-def get_extensions():
+- gen_files_exist = all(os.path.isfile(fn) for fn in GEN_FILES)
+- gen_files_outdated = False
+- if os.path.isdir(ERFA_SRC):
+- # assume thet 'erfaversion.c' is updated at each release at least
+- src = os.path.join(ERFA_SRC, 'erfaversion.c')
+- gen_files_outdated = any(newer(src, fn) for fn in GEN_FILES)
+- elif not gen_files_exist:
+- raise RuntimeError(
+- 'Missing "liberfa" source files, unable to generate '
+- '"erfa/ufunc.c" and "erfa/core.py". '
+- 'Please check your source tree. '
+- 'Maybe "git submodule update" could help.')
+-
+- if not gen_files_exist or gen_files_outdated:
+- print('Run "erfa_generator.py"')
+- #cmd = [sys.executable, 'erfa_generator.py', ERFA_SRC, '--quiet']
+- #subprocess.run(cmd, check=True)
+-
+- gen = import_file(os.path.join(ERFAPKGDIR, 'erfa_generator.py'))
+- gen.main(verbose=False)
+-
+- sources = [os.path.join(ERFAPKGDIR, fn)
+- for fn in ("ufunc.c", "pav2pv.c", "pv2pav.c")]
+- include_dirs = [numpy.get_include()]
+- libraries = []
+-
+- if (int(os.environ.get('ASTROPY_USE_SYSTEM_ERFA', 0)) or
+- int(os.environ.get('ASTROPY_USE_SYSTEM_ALL', 0))):
+- libraries.append('erfa')
+- else:
+- # get all of the .c files in the cextern/erfa directory
+- erfafns = os.listdir(ERFA_SRC)
+- sources.extend(['cextern/erfa/' + fn
+- for fn in erfafns if fn.endswith('.c')])
+-
+- include_dirs.append('cextern/erfa')
+-
+- erfa_ext = Extension(
+- name="astropy._erfa.ufunc",
+- sources=sources,
+- include_dirs=include_dirs,
+- libraries=libraries,
+- language="c",)
+-
+- return [erfa_ext]
+Index: astropy-4.1/astropy/_erfa/tests/__init__.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/tests/__init__.py
++++ /dev/null
+@@ -1 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+Index: astropy-4.1/astropy/_erfa/tests/test_erfa.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/tests/test_erfa.py
++++ /dev/null
+@@ -1,416 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-from datetime import datetime
+-
+-import pytest
+-import numpy as np
+-from numpy.testing import assert_array_equal
+-
+-from astropy import _erfa as erfa
+-from astropy.time import Time
+-from astropy.tests.helper import catch_warnings
+-
+-
+-def test_erfa_wrapper():
+- """
+- Runs a set of tests that mostly make sure vectorization is
+- working as expected
+- """
+-
+- jd = np.linspace(2456855.5, 2456855.5+1.0/24.0/60.0, 60*2+1)
+- ra = np.linspace(0.0, np.pi*2.0, 5)
+- dec = np.linspace(-np.pi/2.0, np.pi/2.0, 4)
+-
+- aob, zob, hob, dob, rob, eo = erfa.atco13(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, jd, 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
+- assert aob.shape == (121,)
+-
+- aob, zob, hob, dob, rob, eo = erfa.atco13(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, jd[0], 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
+- assert aob.shape == ()
+-
+- aob, zob, hob, dob, rob, eo = erfa.atco13(ra[:, None, None], dec[None, :, None], 0.0, 0.0, 0.0, 0.0, jd[None, None, :], 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
+- (aob.shape) == (5, 4, 121)
+-
+- iy, im, id, ihmsf = erfa.d2dtf("UTC", 3, jd, 0.0)
+- assert iy.shape == (121,)
+- assert ihmsf.shape == (121,)
+- assert ihmsf.dtype == erfa.dt_hmsf
+-
+- iy, im, id, ihmsf = erfa.d2dtf("UTC", 3, jd[0], 0.0)
+- assert iy.shape == ()
+- assert ihmsf.shape == ()
+- assert ihmsf.dtype == erfa.dt_hmsf
+-
+-
+-def test_angle_ops():
+-
+- sign, idmsf = erfa.a2af(6, -np.pi)
+- assert sign == b'-'
+- assert idmsf.item() == (180, 0, 0, 0)
+-
+- sign, ihmsf = erfa.a2tf(6, np.pi)
+- assert sign == b'+'
+- assert ihmsf.item() == (12, 0, 0, 0)
+-
+- rad = erfa.af2a('-', 180, 0, 0.0)
+- np.testing.assert_allclose(rad, -np.pi)
+-
+- rad = erfa.tf2a('+', 12, 0, 0.0)
+- np.testing.assert_allclose(rad, np.pi)
+-
+- rad = erfa.anp(3.*np.pi)
+- np.testing.assert_allclose(rad, np.pi)
+-
+- rad = erfa.anpm(3.*np.pi)
+- np.testing.assert_allclose(rad, -np.pi)
+-
+- sign, ihmsf = erfa.d2tf(1, -1.5)
+- assert sign == b'-'
+- assert ihmsf.item() == (36, 0, 0, 0)
+-
+- days = erfa.tf2d('+', 3, 0, 0.0)
+- np.testing.assert_allclose(days, 0.125)
+-
+-
+-def test_spherical_cartesian():
+-
+- theta, phi = erfa.c2s([0.0, np.sqrt(2.0), np.sqrt(2.0)])
+- np.testing.assert_allclose(theta, np.pi/2.0)
+- np.testing.assert_allclose(phi, np.pi/4.0)
+-
+- theta, phi, r = erfa.p2s([0.0, np.sqrt(2.0), np.sqrt(2.0)])
+- np.testing.assert_allclose(theta, np.pi/2.0)
+- np.testing.assert_allclose(phi, np.pi/4.0)
+- np.testing.assert_allclose(r, 2.0)
+-
+- pv = np.array(([0.0, np.sqrt(2.0), np.sqrt(2.0)], [1.0, 0.0, 0.0]),
+- dtype=erfa.dt_pv)
+- theta, phi, r, td, pd, rd = erfa.pv2s(pv)
+- np.testing.assert_allclose(theta, np.pi/2.0)
+- np.testing.assert_allclose(phi, np.pi/4.0)
+- np.testing.assert_allclose(r, 2.0)
+- np.testing.assert_allclose(td, -np.sqrt(2.0)/2.0)
+- np.testing.assert_allclose(pd, 0.0)
+- np.testing.assert_allclose(rd, 0.0)
+-
+- c = erfa.s2c(np.pi/2.0, np.pi/4.0)
+- np.testing.assert_allclose(c, [0.0, np.sqrt(2.0)/2.0, np.sqrt(2.0)/2.0], atol=1e-14)
+-
+- c = erfa.s2p(np.pi/2.0, np.pi/4.0, 1.0)
+- np.testing.assert_allclose(c, [0.0, np.sqrt(2.0)/2.0, np.sqrt(2.0)/2.0], atol=1e-14)
+-
+- pv = erfa.s2pv(np.pi/2.0, np.pi/4.0, 2.0, np.sqrt(2.0)/2.0, 0.0, 0.0)
+- np.testing.assert_allclose(pv['p'], [0.0, np.sqrt(2.0), np.sqrt(2.0)], atol=1e-14)
+- np.testing.assert_allclose(pv['v'], [-1.0, 0.0, 0.0], atol=1e-14)
+-
+-
+-def test_errwarn_reporting():
+- """
+- Test that the ERFA error reporting mechanism works as it should
+- """
+-
+- # no warning
+- erfa.dat(1990, 1, 1, 0.5)
+-
+- # check warning is raised for a scalar
+- with catch_warnings() as w:
+- erfa.dat(100, 1, 1, 0.5)
+- assert len(w) == 1
+- assert w[0].category == erfa.ErfaWarning
+- assert '1 of "dubious year (Note 1)"' in str(w[0].message)
+-
+- # and that the count is right for a vector.
+- with catch_warnings() as w:
+- erfa.dat([100, 200, 1990], 1, 1, 0.5)
+- assert len(w) == 1
+- assert w[0].category == erfa.ErfaWarning
+- assert '2 of "dubious year (Note 1)"' in str(w[0].message)
+-
+- try:
+- erfa.dat(1990, [1, 34, 2], [1, 1, 43], 0.5)
+- except erfa.ErfaError as e:
+- if '1 of "bad day (Note 3)", 1 of "bad month"' not in e.args[0]:
+- assert False, 'Raised the correct type of error, but wrong message: ' + e.args[0]
+-
+- try:
+- erfa.dat(200, [1, 34, 2], [1, 1, 43], 0.5)
+- except erfa.ErfaError as e:
+- if 'warning' in e.args[0]:
+- assert False, 'Raised the correct type of error, but there were warnings mixed in: ' + e.args[0]
+-
+-
+-def test_vector_inouts():
+- """
+- Tests that ERFA functions working with vectors are correctly consumed and spit out
+- """
+-
+- # values are from test_erfa.c t_ab function
+- pnat = [-0.76321968546737951,
+- -0.60869453983060384,
+- -0.21676408580639883]
+- v = [2.1044018893653786e-5,
+- -8.9108923304429319e-5,
+- -3.8633714797716569e-5]
+- s = 0.99980921395708788
+- bm1 = 0.99999999506209258
+-
+- expected = [-0.7631631094219556269,
+- -0.6087553082505590832,
+- -0.2167926269368471279]
+-
+- res = erfa.ab(pnat, v, s, bm1)
+- assert res.shape == (3,)
+-
+- np.testing.assert_allclose(res, expected)
+-
+- res2 = erfa.ab([pnat]*4, v, s, bm1)
+- assert res2.shape == (4, 3)
+- np.testing.assert_allclose(res2, [expected]*4)
+-
+- # here we stride an array and also do it Fortran-order to make sure
+- # it all still works correctly with non-contig arrays
+- pnata = np.array(pnat)
+- arrin = np.array([pnata, pnata/2, pnata/3, pnata/4, pnata/5]*4, order='F')
+- res3 = erfa.ab(arrin[::5], v, s, bm1)
+- assert res3.shape == (4, 3)
+- np.testing.assert_allclose(res3, [expected]*4)
+-
+-
+-def test_pv_in():
+- jd1 = 2456165.5
+- jd2 = 0.401182685
+-
+- pv = np.empty((), dtype=erfa.dt_pv)
+- pv['p'] = [-6241497.16,
+- 401346.896,
+- -1251136.04]
+- pv['v'] = [-29.264597,
+- -455.021831,
+- 0.0266151194]
+-
+- astrom = erfa.apcs13(jd1, jd2, pv)
+- assert astrom.shape == ()
+-
+- # values from t_erfa_c
+- np.testing.assert_allclose(astrom['pmt'], 12.65133794027378508)
+- np.testing.assert_allclose(astrom['em'], 1.010428384373318379)
+- np.testing.assert_allclose(astrom['eb'], [0.9012691529023298391,
+- -.4173999812023068781,
+- -.1809906511146821008])
+- np.testing.assert_allclose(astrom['bpn'], np.eye(3))
+-
+- # first make sure it *fails* if we mess with the input orders
+- pvbad = np.empty_like(pv)
+- pvbad['p'], pvbad['v'] = pv['v'], pv['p']
+- astrombad = erfa.apcs13(jd1, jd2, pvbad)
+- assert not np.allclose(astrombad['em'], 1.010428384373318379)
+-
+- pvarr = np.array([pv]*3)
+- astrom2 = erfa.apcs13(jd1, jd2, pvarr)
+- assert astrom2.shape == (3,)
+- np.testing.assert_allclose(astrom2['em'], 1.010428384373318379)
+-
+- # try striding of the input array to make non-contiguous
+- pvmatarr = np.array([pv]*9)[::3]
+- astrom3 = erfa.apcs13(jd1, jd2, pvmatarr)
+- assert astrom3.shape == (3,)
+- np.testing.assert_allclose(astrom3['em'], 1.010428384373318379)
+-
+-
+-def test_structs():
+- """
+- Checks producing and consuming of ERFA c structs
+- """
+-
+- am, eo = erfa.apci13(2456165.5, [0.401182685, 1])
+- assert am.shape == (2, )
+- assert am.dtype == erfa.dt_eraASTROM
+- assert eo.shape == (2, )
+-
+- # a few spotchecks from test_erfa.c
+- np.testing.assert_allclose(am[0]['pmt'], 12.65133794027378508)
+- np.testing.assert_allclose(am[0]['v'], [0.4289638897157027528e-4,
+- 0.8115034002544663526e-4,
+- 0.3517555122593144633e-4])
+-
+- ri, di = erfa.atciqz(2.71, 0.174, am[0])
+- np.testing.assert_allclose(ri, 2.709994899247599271)
+- np.testing.assert_allclose(di, 0.1728740720983623469)
+-
+-
+-def test_float32_input():
+- # Regression test for gh-8615
+- xyz = np.array([[1, 0, 0], [0.9, 0.1, 0]])
+- out64 = erfa.p2s(xyz)
+- out32 = erfa.p2s(xyz.astype('f4'))
+- np.testing.assert_allclose(out32, out64, rtol=1.e-5)
+-
+-
+-class TestAstromNotInplace:
+- def setup(self):
+- self.mjd_array = np.array(
+- [58827.15925499, 58827.15925499, 58827.15925499,
+- 58827.15925499, 58827.15925499])
+- self.mjd_scalar = self.mjd_array[0].item()
+- self.utc2mjd = 2400000.5
+- paranal_long = -1.228798
+- paranal_lat = -0.42982
+- paranal_height = 2669.
+- self.astrom_scalar, _ = erfa.apco13(
+- self.utc2mjd, self.mjd_scalar, 0.0, paranal_long, paranal_lat,
+- paranal_height, 0.0, 0.0, 0.0, 0.0, 0.0, 2.5)
+- self.astrom_array, _ = erfa.apco13(
+- self.utc2mjd, self.mjd_array, 0.0, paranal_long, paranal_lat,
+- paranal_height, 0.0, 0.0, 0.0, 0.0, 0.0, 2.5)
+-
+- def test_scalar_input(self):
+- # Regression test for gh-9799, where astrom0 being a void
+- # caused a TypeError, as it was trying to change it in-place.
+- assert type(self.astrom_scalar) is np.void
+- astrom = erfa.aper13(self.utc2mjd, self.mjd_scalar, self.astrom_scalar)
+- assert astrom is not self.astrom_scalar
+- assert type(astrom) is np.void
+-
+- def test_array_input(self):
+- # Trying to fix gh-9799, it became clear that doing things in-place was
+- # a bad idea generally (and didn't work), so also for array input we
+- # now return a copy.
+- assert type(self.astrom_array) is np.ndarray
+- astrom = erfa.aper13(self.utc2mjd, self.mjd_array, self.astrom_array)
+- assert astrom is not self.astrom_array
+- assert type(astrom) is np.ndarray
+-
+-
+-class TestLeapSecondsBasics:
+- def test_get_leap_seconds(self):
+- leap_seconds = erfa.leap_seconds.get()
+- assert isinstance(leap_seconds, np.ndarray)
+- assert leap_seconds.dtype is erfa.dt_eraLEAPSECOND
+- # Very basic sanity checks.
+- assert np.all((leap_seconds['year'] >= 1960) &
+- (leap_seconds['year'] < 3000))
+- assert np.all((leap_seconds['month'] >= 1) &
+- (leap_seconds['month'] <= 12))
+- assert np.all(abs(leap_seconds['tai_utc'] < 1000.))
+-
+- def test_leap_seconds_expires(self):
+- expires = erfa.leap_seconds.expires
+- assert isinstance(expires, datetime)
+- last_ls = erfa.leap_seconds.get()[-1]
+- dt_last = datetime(last_ls['year'], last_ls['month'], 1)
+- assert expires > dt_last
+-
+-
+-class TestLeapSeconds:
+- """Test basic methods to control the ERFA leap-second table."""
+- def setup(self):
+- self.erfa_ls = erfa.leap_seconds.get()
+- self.expires = erfa.leap_seconds.expires
+- self._expires = erfa.leap_seconds._expires
+-
+- def teardown(self):
+- erfa.leap_seconds.set(self.erfa_ls)
+- erfa.leap_seconds._expires = self._expires
+-
+- def test_set_reset_leap_seconds(self):
+- erfa.leap_seconds.set()
+- leap_seconds = erfa.leap_seconds.get()
+-
+- erfa.leap_seconds.set(leap_seconds[:-2])
+- new_leap_seconds = erfa.leap_seconds.get()
+- assert_array_equal(new_leap_seconds, leap_seconds[:-2])
+-
+- erfa.leap_seconds.set()
+- reset_leap_seconds = erfa.leap_seconds.get()
+- assert_array_equal(reset_leap_seconds, leap_seconds)
+-
+- def test_set_leap_seconds(self):
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+- leap_seconds = erfa.leap_seconds.get()
+- # Set to a table that misses the 2017 leap second.
+- part_leap_seconds = leap_seconds[leap_seconds['year'] < 2017]
+- erfa.leap_seconds.set(part_leap_seconds)
+- new_leap_seconds = erfa.leap_seconds.get()
+- assert_array_equal(new_leap_seconds, part_leap_seconds)
+- # Check the 2017 leap second is indeed missing.
+- assert erfa.dat(2018, 1, 1, 0.) == 36.0
+- # And that this would be expected from the expiration date.
+- assert erfa.leap_seconds.expires < datetime(2018, 1, 1)
+- assert erfa.leap_seconds.expired
+- # Reset and check it is back.
+- erfa.leap_seconds.set()
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+-
+- @pytest.mark.parametrize('table,match', [
+- ([(2017, 3, 10.)], 'January'),
+- ([(2017, 1, 1.),
+- (2017, 7, 3.)], 'jump'),
+- ([[(2017, 1, 1.)],
+- [(2017, 7, 2.)]], 'dimension')])
+- def test_validation(self, table, match):
+- with pytest.raises(ValueError, match=match):
+- erfa.leap_seconds.set(table)
+- # Check leap-second table is not corrupted.
+- assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+-
+- def test_update_leap_seconds(self):
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+- leap_seconds = erfa.leap_seconds.get()
+- # Get old and new leap seconds
+- old_leap_seconds = leap_seconds[leap_seconds['year'] < 2017]
+- new_leap_seconds = leap_seconds[leap_seconds['year'] >= 2017]
+- # Updating with either of these should do nothing.
+- n_update = erfa.leap_seconds.update(new_leap_seconds)
+- assert n_update == 0
+- assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)
+- n_update = erfa.leap_seconds.update(old_leap_seconds)
+- assert n_update == 0
+- assert_array_equal(erfa.leap_seconds.get(), self.erfa_ls)
+-
+- # But after setting to older part, update with newer should work.
+- erfa.leap_seconds.set(old_leap_seconds)
+- # Check the 2017 leap second is indeed missing.
+- assert erfa.dat(2018, 1, 1, 0.) == 36.0
+- # Update with missing leap seconds.
+- n_update = erfa.leap_seconds.update(new_leap_seconds)
+- assert n_update == len(new_leap_seconds)
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+-
+- # Also a final try with overlapping data.
+- erfa.leap_seconds.set(old_leap_seconds)
+- n_update = erfa.leap_seconds.update(leap_seconds)
+- assert n_update == len(new_leap_seconds)
+- assert erfa.dat(2018, 1, 1, 0.) == 37.0
+-
+- @pytest.mark.parametrize('expiration', [
+- datetime(2345, 1, 1),
+- '1 January 2345',
+- Time('2345-01-01', scale='tai')])
+- def test_with_expiration(self, expiration):
+- class ExpiringArray(np.ndarray):
+- expires = expiration
+-
+- leap_seconds = erfa.leap_seconds.get()
+- erfa.leap_seconds.set(leap_seconds.view(ExpiringArray))
+- assert erfa.leap_seconds.expires == datetime(2345, 1, 1)
+-
+- # Get old and new leap seconds
+- old_leap_seconds = leap_seconds[:-10]
+- new_leap_seconds = leap_seconds[-10:]
+-
+- erfa.leap_seconds.set(old_leap_seconds)
+- # Check expiration is reset
+- assert erfa.leap_seconds.expires != datetime(2345, 1, 1)
+- # Update with missing leap seconds.
+- n_update = erfa.leap_seconds.update(
+- new_leap_seconds.view(ExpiringArray))
+- assert n_update == len(new_leap_seconds)
+- assert erfa.leap_seconds.expires == datetime(2345, 1, 1)
+-
+- def test_with_expiration_warning(self):
+- class ExpiringArray(np.ndarray):
+- expires = 'incomprehensible'
+-
+- leap_seconds = erfa.leap_seconds.get()
+- with pytest.warns(erfa.ErfaWarning,
+- match='non-datetime.*parsing it raised'):
+- erfa.leap_seconds.set(leap_seconds.view(ExpiringArray))
+Index: astropy-4.1/astropy/_erfa/ufunc.c.templ
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/ufunc.c.templ
++++ /dev/null
+@@ -1,921 +0,0 @@
+-/* -*- mode: c -*- */
+-
+-/* Licensed under a 3-clause BSD style license - see LICENSE.rst */
+-
+-/*
+- * "ufunc.c" is auto-generated by erfa_generator.py from the template
+- * "ufunc.c.templ". Do *not* edit "ufunc.c" directly, instead edit
+- * "ufunc.c.templ" and run ufunc_generator.py from the source directory
+- * to update it.
+- */
+-
+-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+-#include "Python.h"
+-#include "numpy/arrayobject.h"
+-#include "numpy/ufuncobject.h"
+-#include "erfa.h"
+-#include "erfaextra.h"
+-#include "erfa_additions.h"
+-
+-#define MODULE_DOCSTRING \
+- "Ufunc wrappers of the ERFA routines.\n\n" \
+- "These ufuncs vectorize the ERFA functions assuming structured dtypes\n" \
+- "for vector and matrix arguments. Status codes are vectors as well.\n" \
+- "Python wrappers are also provided, which convert between\n" \
+- "trailing dimensions and structured dtypes where necessary,\n" \
+- "and combine status codes."
+-#define GET_LEAP_SECONDS_DOCSTRING \
+- "get_leap_seconds()\n\n" \
+- "Access the leap second table used in ERFA.\n\n" \
+- "Returns\n" \
+- "-------\n" \
+- "leap_seconds : `~numpy.ndarray`\n" \
+- " With structured dtype `~astropy._erfa.dt_eraLEAPSECOND`,\n" \
+- " containing items 'year', 'month', and 'tai_utc'."
+-#define SET_LEAP_SECONDS_DOCSTRING \
+- "set_leap_seconds([table])\n\n" \
+- "Set the leap second table used in ERFA.\n\n" \
+- "Parameters\n" \
+- "----------\n" \
+- "leap_seconds : array_like, optional\n" \
+- " With structured dtype `~astropy._erfa.dt_eraLEAPSECOND`,\n" \
+- " containing items 'year', 'month', and 'tai_utc'.\n" \
+- " If not given, reset to the ERFA built-in table.\n\n" \
+- "Notes\n" \
+- "-----\n" \
+- "No sanity checks are done on the input; it is simply coerced\n" \
+- "to the correct dtype."
+-
+-
+-static inline void copy_to_double3(char *ptr, npy_intp s, double d[3]) {
+- char *p = ptr;
+- int j;
+- for (j = 0; j < 3; j++, p += s) {
+- d[j] = *(double *)p;
+- }
+-}
+-
+-static inline void copy_from_double3(char *ptr, npy_intp s, double d[3]) {
+- char *p = ptr;
+- int j;
+- for (j = 0; j < 3; j++, p += s) {
+- *(double *)p = d[j];
+- }
+-}
+-
+-static inline void copy_to_double33(char *ptr, npy_intp s0, npy_intp s1,
+- double d[3][3]) {
+- char *p0 = ptr;
+- int j0, j1;
+- for (j0 = 0; j0 < 3; j0++, p0 += s0) {
+- char *p1 = p0;
+- for (j1 = 0; j1 < 3; j1++, p1 += s1) {
+- d[j0][j1] = *(double *)p1;
+- }
+- }
+-}
+-
+-static inline void copy_from_double33(char *ptr, npy_intp s0, npy_intp s1,
+- double d[3][3]) {
+- char *p = ptr;
+- char *p0 = ptr;
+- int j0, j1;
+- for (j0 = 0; j0 < 3; j0++, p0 += s0) {
+- char *p1 = p0;
+- for (j1 = 0; j1 < 3; j1++, p1 += s1) {
+- *(double *)p = d[j0][j1];
+- }
+- }
+-}
+-
+-/* eraLDBODY is never returned, so we do not need a copy_from */
+-static inline void copy_to_eraLDBODY(char *ptr, npy_intp s, npy_intp n,
+- eraLDBODY b[]) {
+- char *p = ptr;
+- npy_intp j;
+- for (j = 0; j < n; j++, p += s) {
+- b[j] = *(eraLDBODY *)p;
+- }
+-}
+-
+-/*
+- * INNER LOOPS - iteratively call the erfa function for a chunk of data.
+- *
+- * For each argument:
+- * char * is the pointer to the data in memory;
+- * npy_intp s_ is the number of bytes between successive elements;
+- * *_ is a correctly cast pointer to the current element;
+- * ( _, i.e., not a pointer, for status codes and return values)
+- *
+- * Notes:
+- * 1. Some erfa function change elements in-place; in the ufunc, these "inout"
+- * arguments are treated as separate: data is copied from the input to the
+- * output, and the output is changed in-place by the erfa function.
+- * To reproduce the in-place behaviour, the input to the ufunc can be passed
+- * in as output as well -- as is done in the python wrapper (the copy will
+- * be omitted for this case).
+- * 2. Any erfa function involving light deflection requires an struct
+- * eraLDBODY argument with a dimension that is user-defined. Those function
+- * are implemented as generalized ufuncs, with a signature in which the
+- * relevant variable is marked (i.e., '(),...,(n), (), ... -> (),...').
+- * In the inner loops, an appropriate copy is done if in the numpy array
+- * the n elements are not contiguous.
+- * 3. Similar copies are done for erfa functions that require vectors or
+- * matrices, if the corresponding axes in the input or output operands are
+- * not contiguous.
+- */
+-
+-{%- macro inner_loop_steps_and_copy(arg, arg_name) %}
+- {%- for i in range(arg.ndim or 1) %}
+- npy_intp is_{{ arg_name }}{{ i }} = *steps++;
+- {%- endfor %}
+- {#- /* copy should be made if buffer not contiguous;
+- note: one can only have 1 or 2 dimensions */ #}
+- {%- if arg.ndim == 2 %}
+- int copy_{{ arg_name
+- }} = (is_{{ arg_name }}1 != sizeof({{ arg.ctype }}) &&
+- is_{{ arg_name }}0 != {{ arg.shape[1] }} * sizeof({{ arg.ctype }}));
+- {%- else %}
+- int copy_{{ arg_name }} = (is_{{ arg_name }}0 != sizeof({{ arg.ctype }}));
+- {%- endif %}
+-{%- endmacro %}
+-
+-{%- for func in funcs %}
+-
+-static void ufunc_loop_{{ func.pyname }}(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- {#- /* index and length of loop */ #}
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- {#- /*
+- * Pointers to each argument, required step size
+- */ #}
+- {#- /* normal input arguments */ #}
+- {%- for arg in func.args_by_inout('in') %}
+- char *{{ arg.name }} = *args++;
+- npy_intp s_{{ arg.name }} = *steps++;
+- {%- endfor -%}
+- {#- /* for in part of in-place arguments, we need a different name */ #}
+- {%- for arg in func.args_by_inout('inout') %}
+- char *{{ arg.name }}_in = *args++;
+- npy_intp s_{{ arg.name }}_in = *steps++;
+- {%- endfor -%}
+- {#- /* out part of input, and output arguments, including status */ #}
+- {%- for arg in func.args_by_inout('inout|out|stat|ret') %}
+- char *{{ arg.name }} = *args++;
+- npy_intp s_{{ arg.name }} = *steps++;
+- {%- endfor -%}
+- {#- /*
+- * Cast pointers and possible contiguous buffers (for gufuncs)
+- */ #}
+- {%- for arg in func.args_by_inout('in|inout|out') %}
+- {%- if arg.signature_shape == '()' or arg.ctype == 'eraLDBODY' %}
+- {{ arg.ctype }} (*_{{ arg.name }}){{ arg.cshape }};
+- {%- else %}
+- double b_{{ arg.name }}{{ arg.cshape }};
+- {{ arg.ctype }} (*_{{ arg.name }}){{ arg.cshape }} = &b_{{ arg.name }};
+- {%- endif %}
+- {%- endfor %}
+- {#- /* variables to hold status and return values */ #}
+- {%- for arg in func.args_by_inout('stat|ret') %}
+- {{ arg.ctype }} _{{ arg.name }};
+- {%- endfor %}
+- {#- /*
+- * For GENERALIZED UFUNCS - inner loop steps, needs for copying.
+- */ #}
+- {%- if func.signature %}
+- {#- /* loop step sizes and whether copies are needed */ #}
+- {%- for arg in func.args_by_inout('in') %}
+- {#- /* only LDBODY has non-fixed dimension; it is always first */ #}
+- {%- if arg.ctype == 'eraLDBODY' %}
+- npy_intp nb = dimensions[0];
+- {%- endif %}
+- {%- if arg.signature_shape != '()' -%}
+- {{ inner_loop_steps_and_copy(arg, arg.name) }}
+- {%- endif %}
+- {%- endfor %}
+- {%- for arg in func.args_by_inout('inout') %}
+- {%- if arg.signature_shape != '()' -%}
+- {{ inner_loop_steps_and_copy(arg, arg.name + '_in') }}
+- {%- endif %}
+- {%- endfor %}
+- {%- for arg in func.args_by_inout('inout|out') %}
+- {%- if arg.signature_shape != '()' -%}
+- {{ inner_loop_steps_and_copy(arg, arg.name) }}
+- {%- endif %}
+- {%- endfor %}
+- {#- /* if needed, allocate memory for contiguous eraLDBODY copies */ #}
+- {%- if func.user_dtype == 'dt_eraLDBODY' %}
+- if (copy_b) {
+- _b = PyArray_malloc(nb * sizeof(eraLDBODY));
+- if (_b == NULL) {
+- PyErr_NoMemory();
+- return;
+- }
+- }
+- else { {#- /* just to keep compiler happy */ #}
+- _b = NULL;
+- }
+- {%- endif %}
+- {%- endif %} {#- /* end of GUFUNC inner loop definitions */ #}
+- {#- /*
+- * Actual inner loop, increasing all pointers by their steps
+- */ #}
+- for (i_o = 0; i_o < n_o;
+- i_o++ {%- for arg in func.args_by_inout('in|inout|out|stat|ret') -%}
+- , {{ arg.name }} += s_{{ arg.name }}
+- {%- endfor -%}
+- {%- for arg in func.args_by_inout('inout') -%}
+- , {{ arg.name }}_in += s_{{ arg.name }}_in
+- {%- endfor -%}) {
+- {%- if func.signature %}
+- {#- /*
+- * GENERALIZED UFUNC, prepare for call.
+- */ #}
+- {#- /* copy input arguments to buffer if needed */ #}
+- {%- for arg in func.args_by_inout('in') %}
+- {%- if arg.signature_shape != '()' %}
+- if (copy_{{ arg.name }}) {
+- copy_to_{{ arg.ctype }}{{ arg.shape|join('') }}({{ arg.name }}
+- {%- for i in range(arg.ndim or 1) -%}
+- , is_{{ arg.name }}{{ i }}
+- {%- endfor %}, {{ arg.name_for_call}});
+- }
+- else {
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- }
+- {%- else %}
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- {%- endif %}
+- {%- endfor %} {#- end of loop over 'in' #}
+- {#- /* for inout arguments, set up output first,
+- and then copy to it if needed */ #}
+- {%- for arg in func.args_by_inout('inout') %}
+- {%- if arg.signature_shape != '()' %}
+- if (!copy_{{ arg.name }}) {
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- }
+- if (copy_{{ arg.name }}_in || {{ arg.name }} != {{ arg.name }}_in) {
+- copy_to_{{ arg.ctype }}{{ arg.shape|join('') }}({{ arg.name }}_in
+- {%- for i in range(arg.ndim or 1) -%}
+- , is_{{ arg.name }}_in{{ i }}
+- {%- endfor %}, {{ arg.name_for_call}});
+- }
+- {%- else %}
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- if ({{ arg.name }}_in != {{ arg.name }}) {
+- memcpy({{ arg.name }}, {{ arg.name }}_in, {{ arg.size }}*sizeof({{ arg.ctype }}));
+- }
+- {%- endif %}
+- {%- endfor %} {#- end of loop over 'inout' #}
+- {#- /* set up gufunc outputs */ #}
+- {%- for arg in func.args_by_inout('out') %}
+- {%- if arg.signature_shape != '()' %}
+- if (!copy_{{ arg.name }}) {
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- }
+- {%- else %}
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- {%- endif %}
+- {%- endfor %} {#- end of loop over 'out' #}
+- {%- else %}
+- {#- /*
+- * NORMAL UFUNC, prepare for call
+- */ #}
+- {#- /* set up pointers to input/output arguments */ #}
+- {%- for arg in func.args_by_inout('in|inout|out') %}
+- _{{ arg.name }} = (({{ arg.ctype }} (*){{ arg.cshape }}){{ arg.name }});
+- {%- endfor %}
+- {#- /* copy from in to out for arugments changed in-place */ #}
+- {%- for arg in func.args_by_inout('inout') %}
+- if ({{ arg.name }}_in != {{ arg.name }}) {
+- memcpy({{ arg.name }}, {{ arg.name }}_in, {{ arg.size }}*sizeof({{ arg.ctype }}));
+- }
+- {%- endfor %}
+- {%- endif %} {#- end of gufunc/ufunc preparation #}
+- {#- /*
+- * call the actual erfa function
+- */ #}
+- {{ func.args_by_inout('ret|stat') |
+- map(attribute='name') |
+- surround('_', ' = ') |
+- join
+- }}{{ func.name
+- }}({{ func.args_by_inout('in|inout|out') |
+- map(attribute='name_for_call') |
+- join(', ') }});
+- {#- /* store any return values */ #}
+- {%- for arg in func.args_by_inout('ret|stat') %}
+- *(({{ arg.ctype }} *){{ arg.name }}) = _{{ arg.name }};
+- {%- endfor %}
+- {%- if func.signature %}
+- {#- /* for generalized ufunc, copy output from buffer if needed */ #}
+- {%- for arg in func.args_by_inout('inout|out') %}
+- {%- if arg.signature_shape != '()' %}
+- if (copy_{{ arg.name }}) {
+- copy_from_{{ arg.ctype }}{{ arg.shape|join('') }}({{ arg.name }}
+- {%- for i in range(arg.ndim or 1) -%}
+- , is_{{ arg.name }}{{ i }}
+- {%- endfor %}, {{ arg.name_for_call}});
+- }
+- {%- endif %}
+- {%- endfor %}
+- {%- endif %}
+- }
+- {%- if func.user_dtype == 'dt_eraLBODY' %}
+- if (copy_b) {
+- PyArray_free(_b);
+- }
+- {%- endif %}
+-}
+-
+-{%- endfor %}
+-
+-/*
+- * UFUNC LOOP MATCHING HELPERS
+- * All but ufunc_loop_matches are copies of code needed but not exported.
+- */
+-
+-/*
+- * Adjusted version of ufunc_loop_matches from
+- * numpy/core/src/umath/ufunc_type_resolution.c.
+- * Here, we special-case the structured dtype check, only allowing
+- * casting of the same dtype or string. We also do not distinguish
+- * between input and output arguments for casting.
+- */
+-static int
+-ufunc_loop_matches(PyUFuncObject *self,
+- PyArrayObject **op,
+- NPY_CASTING casting,
+- int *types, PyArray_Descr **dtypes)
+-{
+- npy_intp i, nin = self->nin, nop = nin + self->nout;
+- /*
+- * Check if all the inputs can be cast to the types used by this function.
+- */
+- for (i = 0; i < nin; ++i) {
+- PyArray_Descr *op_descr = PyArray_DESCR(op[i]);
+- /*
+- * Check for NPY_VOID with an associated struct dtype.
+- */
+- if (types[i] == NPY_VOID && dtypes != NULL) {
+- int op_descr_type_num = op_descr->type_num;
+- int dtype_elsize = dtypes[i]->elsize;
+- /*
+- * MHvK: we do our own check on casting, since by default
+- * all items can cast to structured dtypes (see gh-11114),
+- * which is not OK. So, we only allow VOID->same VOID,
+- * and STRING -> VOID-of-STRING (which works well; we
+- * recognize VOID-of-STRING by the dtype element size;
+- * it would be rather costly to go look at dtype->fields).
+- */
+- if (op_descr_type_num == NPY_VOID) {
+- /* allow only the same structured to structured */
+- if (!PyArray_EquivTypes(op_descr, dtypes[i])) {
+- return 0;
+- }
+- }
+- else if (dtypes[i]->elsize == 1 || dtypes[i]->elsize == 12) {
+- /* string structured array; string argument is OK */
+- if (!((op_descr_type_num == NPY_STRING &&
+- op_descr->elsize <= dtype_elsize) ||
+- (op_descr_type_num == NPY_UNICODE &&
+- op_descr->elsize >> 2 <= dtype_elsize))) {
+- return 0;
+- }
+- }
+- else {
+- return 0;
+- }
+- }
+- else { /* non-void function argument */
+- PyArray_Descr *tmp = PyArray_DescrFromType(types[i]);
+- if (tmp == NULL) {
+- return -1;
+- }
+- if (!PyArray_CanCastTypeTo(op_descr, tmp, casting)) {
+- Py_DECREF(tmp);
+- return 0;
+- }
+- Py_DECREF(tmp);
+- }
+- }
+- /*
+- * All inputs were ok; now check casting back to the outputs.
+- * MHvK: Since no casting from structured to non-structured is
+- * possible, no changes needed here.
+- */
+- for (i = nin; i < nop; ++i) {
+- if (op[i] != NULL) {
+- PyArray_Descr *tmp = PyArray_DescrFromType(types[i]);
+- if (tmp == NULL) {
+- return -1;
+- }
+- if (!PyArray_CanCastTypeTo(tmp, PyArray_DESCR(op[i]),
+- casting)) {
+- Py_DECREF(tmp);
+- return 0;
+- }
+- Py_DECREF(tmp);
+- }
+- }
+- return 1;
+-}
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since this translation function is not exported.
+- */
+-static const char *
+-npy_casting_to_string(NPY_CASTING casting)
+-{
+- switch (casting) {
+- case NPY_NO_CASTING:
+- return "'no'";
+- case NPY_EQUIV_CASTING:
+- return "'equiv'";
+- case NPY_SAFE_CASTING:
+- return "'safe'";
+- case NPY_SAME_KIND_CASTING:
+- return "'same_kind'";
+- case NPY_UNSAFE_CASTING:
+- return "'unsafe'";
+- default:
+- return "";
+- }
+-}
+-
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since not exported.
+- */
+-static PyArray_Descr *
+-ensure_dtype_nbo(PyArray_Descr *type)
+-{
+- if (PyArray_ISNBO(type->byteorder)) {
+- Py_INCREF(type);
+- return type;
+- }
+- else {
+- return PyArray_DescrNewByteorder(type, NPY_NATIVE);
+- }
+-}
+-
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since not exported.
+- */
+-static int
+-set_ufunc_loop_data_types(PyUFuncObject *self, PyArrayObject **op,
+- PyArray_Descr **out_dtypes,
+- int *type_nums, PyArray_Descr **dtypes)
+-{
+- int i, nin = self->nin, nop = nin + self->nout;
+-
+- /*
+- * Fill the dtypes array.
+- * For outputs,
+- * also search the inputs for a matching type_num to copy
+- * instead of creating a new one, similarly to preserve metadata.
+- **/
+- for (i = 0; i < nop; ++i) {
+- if (dtypes != NULL) {
+- out_dtypes[i] = dtypes[i];
+- Py_XINCREF(out_dtypes[i]);
+- /*
+- * Copy the dtype from 'op' if the type_num matches,
+- * to preserve metadata.
+- */
+- }
+- else if (op[i] != NULL &&
+- PyArray_DESCR(op[i])->type_num == type_nums[i]) {
+- out_dtypes[i] = ensure_dtype_nbo(PyArray_DESCR(op[i]));
+- }
+- /*
+- * For outputs, copy the dtype from op[0] if the type_num
+- * matches, similarly to preserve metdata.
+- */
+- else if (i >= nin && op[0] != NULL &&
+- PyArray_DESCR(op[0])->type_num == type_nums[i]) {
+- out_dtypes[i] = ensure_dtype_nbo(PyArray_DESCR(op[0]));
+- }
+- /* Otherwise create a plain descr from the type number */
+- else {
+- out_dtypes[i] = PyArray_DescrFromType(type_nums[i]);
+- }
+-
+- if (out_dtypes[i] == NULL) {
+- goto fail;
+- }
+- }
+-
+- return 0;
+-
+-fail:
+- while (--i >= 0) {
+- Py_DECREF(out_dtypes[i]);
+- out_dtypes[i] = NULL;
+- }
+- return -1;
+-}
+-
+-/*
+- * UFUNC TYPE RESOLVER
+- *
+- * We provide our own type resolver, since the default one,
+- * PyUFunc_DefaultTypeResolver from
+- * numpy/core/src/umath/ufunc_type_resolution.c, has problems:
+- * 1. It only looks for userloops if any of the operands have a user
+- * type, which does not work if the inputs are normal and no explicit
+- * output is given (see https://github.com/numpy/numpy/issues/11109).
+- * 2. It only allows "safe" casting of inputs, which annoyingly prevents
+- * passing in a python int for int32 input.
+- * The resolver below solves both, and speeds up the process by
+- * explicitly assuming that a ufunc has only one function built in,
+- * either a regular one or a userloop (for structured dtype).
+- *
+- * Combines code from linear_search_type_resolver and
+- * linear_search_userloop_type_resolver from
+- * numpy/core/src/umath/ufunc_type_resolution.c
+- */
+-static int ErfaUFuncTypeResolver(PyUFuncObject *ufunc,
+- NPY_CASTING casting,
+- PyArrayObject **operands,
+- PyObject *type_tup,
+- PyArray_Descr **out_dtypes)
+-{
+- int *types;
+- PyArray_Descr **dtypes;
+-
+- if (ufunc->userloops) {
+- Py_ssize_t unused_pos = 0;
+- PyObject *userloop;
+- PyUFunc_Loop1d *funcdata;
+-
+- if (ufunc->ntypes > 0 || PyDict_Size(ufunc->userloops) != 1) {
+- goto fail;
+- }
+- /* No iteration needed; only one entry in dict */
+- PyDict_Next(ufunc->userloops, &unused_pos, NULL, &userloop);
+- funcdata = (PyUFunc_Loop1d *)PyCapsule_GetPointer(userloop, NULL);
+- /* There should be only one function */
+- if (funcdata->next != NULL) {
+- goto fail;
+- }
+- types = funcdata->arg_types;
+- dtypes = funcdata->arg_dtypes;
+- }
+- else {
+- npy_intp j;
+- int types_array[NPY_MAXARGS];
+-
+- if (ufunc->ntypes != 1) {
+- goto fail;
+- }
+- /* Copy the types into an int array for matching */
+- for (j = 0; j < ufunc->nargs; ++j) {
+- types_array[j] = ufunc->types[j];
+- }
+- types = types_array;
+- dtypes = NULL;
+- }
+- switch (ufunc_loop_matches(ufunc, operands, casting, types, dtypes)) {
+- case 1: /* Matching types */
+- return set_ufunc_loop_data_types(ufunc, operands, out_dtypes,
+- types, dtypes);
+- case -1: /* Error */
+- return -1;
+- }
+- /* No match */
+- PyErr_Format(PyExc_TypeError,
+- "ufunc '%s' not supported for the input types, and the "
+- "inputs could not be safely coerced to any supported "
+- "types according to the casting rule '%s'",
+- ufunc->name, npy_casting_to_string(casting));
+- return -1;
+-
+-fail:
+- /* More than one loop or function */
+- PyErr_Format(PyExc_RuntimeError,
+- "Unexpected internal error: ufunc '%s' wraps an ERFA "
+- "function and should have only a single loop with a "
+- "single function, yet has more.",
+- ufunc->name);
+- return -1;
+-}
+-
+-/*
+- * LEAP SECOND ACCESS
+- *
+- * Getting/Setting ERFAs built-in TAI-UTC table.
+- *
+- * TODO: the whole procedure is not sub-interpreter safe.
+- * In this module, one might get dt_eraLEAPSECOND out of the module dict,
+- * and store the leap_second array in a per-module struct (see PEP 3121).
+- * But one then would also have to adapt erfa/dat.c to not use a
+- * static leap second table. Possibly best might be to copy dat.c here
+- * and put the table into the per-module struct as well.
+- */
+-static PyArray_Descr *dt_eraLEAPSECOND = NULL; /* Set in PyInit_ufunc */
+-
+-static PyObject *
+-get_leap_seconds(PyObject *NPY_UNUSED(module), PyObject *NPY_UNUSED(args)) {
+- eraLEAPSECOND *leapseconds;
+- npy_intp count;
+- PyArrayObject *array;
+- /* Get the leap seconds from ERFA */
+- count = (npy_intp)eraGetLeapSeconds(&leapseconds);
+- if (count < 0) {
+- PyErr_SetString(PyExc_RuntimeError,
+- "Unpexected failure to get ERFA leap seconds.");
+- return NULL;
+- }
+- /* Allocate an array to hold them */
+- Py_INCREF(dt_eraLEAPSECOND);
+- array = (PyArrayObject *)PyArray_NewFromDescr(
+- &PyArray_Type, dt_eraLEAPSECOND, 1, &count, NULL, NULL, 0, NULL);
+- if (array == NULL) {
+- return NULL;
+- }
+- /* Copy the leap seconds over into the array */
+- memcpy(PyArray_DATA(array), leapseconds, count*sizeof(eraLEAPSECOND));
+- return (PyObject *)array;
+-}
+-
+-static PyObject *
+-set_leap_seconds(PyObject *NPY_UNUSED(module), PyObject *args) {
+- PyObject *leap_seconds = NULL;
+- PyArrayObject *array;
+- static PyArrayObject *leap_second_array = NULL;
+-
+- if (!PyArg_ParseTuple(args, "|O:set_leap_seconds", &leap_seconds)) {
+- return NULL;
+- }
+- if (leap_seconds != NULL && leap_seconds != Py_None) {
+- /*
+- * Convert the input to an array with the proper dtype;
+- * Ensure a copy is made so one cannot change the data by changing
+- * the input array.
+- */
+- Py_INCREF(dt_eraLEAPSECOND);
+- array = (PyArrayObject *)PyArray_FromAny(leap_seconds, dt_eraLEAPSECOND,
+- 1, 1, (NPY_ARRAY_CARRAY | NPY_ARRAY_ENSURECOPY), NULL);
+- if (array == NULL) {
+- return NULL;
+- }
+- if (PyArray_SIZE(array) == 0) {
+- PyErr_SetString(PyExc_ValueError,
+- "Leap second array must have at least one entry.");
+- }
+- /*
+- * Use the array for the new leap seconds.
+- */
+- eraSetLeapSeconds(PyArray_DATA(array), PyArray_SIZE(array));
+- }
+- else {
+- /*
+- * If no input is given, reset leap second table.
+- */
+- array = NULL;
+- eraSetLeapSeconds(NULL, 0);
+- }
+- /*
+- * If we allocated a leap second array before, deallocate it,
+- * and set it to remember any allocation from PyArray_FromAny.
+- */
+- if (leap_second_array != NULL) {
+- Py_DECREF(leap_second_array);
+- }
+- leap_second_array = array;
+- Py_RETURN_NONE;
+-}
+-
+-/*
+- * UFUNC MODULE DEFINITIONS AND INITIALIZATION
+- */
+-static PyMethodDef ErfaUFuncMethods[] = {
+- {"get_leap_seconds", (PyCFunction)get_leap_seconds,
+- METH_NOARGS, GET_LEAP_SECONDS_DOCSTRING},
+- {"set_leap_seconds", (PyCFunction)set_leap_seconds,
+- METH_VARARGS, SET_LEAP_SECONDS_DOCSTRING},
+- {NULL, NULL, 0, NULL}
+-};
+-
+-static struct PyModuleDef moduledef = {
+- PyModuleDef_HEAD_INIT,
+- "ufunc",
+- MODULE_DOCSTRING,
+- -1,
+- ErfaUFuncMethods,
+- NULL,
+- NULL,
+- NULL,
+- NULL
+-};
+-
+-PyMODINIT_FUNC PyInit_ufunc(void)
+-{
+- /* module and its dict */
+- PyObject *m, *d;
+- /* structured dtypes and their definition */
+- PyObject *dtype_def;
+- PyArray_Descr *dt_double = NULL, *dt_int = NULL;
+- PyArray_Descr *dt_pv = NULL, *dt_pvdpv = NULL;
+- PyArray_Descr *dt_ymdf = NULL, *dt_hmsf = NULL, *dt_dmsf = NULL;
+- PyArray_Descr *dt_sign = NULL, *dt_type = NULL;
+- PyArray_Descr *dt_eraASTROM = NULL, *dt_eraLDBODY = NULL;
+- PyArray_Descr *dtypes[NPY_MAXARGS];
+- /* ufuncs and their definitions */
+- int status;
+- PyUFuncObject *ufunc;
+- static void *data[1] = {NULL};
+- {#- /* for non-structured functions, define there types and functions
+- as these do not get copied */ #}
+- {%- for func in funcs %}
+- {%- if not func.user_dtype %}
+- static char types_{{ func.pyname }}[{{ func.args_by_inout('in|inout|out|ret|stat')|count }}] = { {{ func.args_by_inout('in|inout|out|ret|stat')|map(attribute='npy_type')|join(', ') }} };
+- static PyUFuncGenericFunction funcs_{{ func.pyname }}[1] = { &ufunc_loop_{{ func.pyname }} };
+- {%- endif %}
+- {%- endfor %}
+-
+- m = PyModule_Create(&moduledef);
+- if (m == NULL) {
+- return NULL;
+- }
+- d = PyModule_GetDict(m); /* borrowed ref. */
+- if (d == NULL) {
+- goto fail;
+- }
+-
+- import_array();
+- import_umath();
+- /*
+- * Define the basic and structured types used in erfa so that
+- * we can use them for definitions of userloops below.
+- */
+- dt_double = PyArray_DescrFromType(NPY_DOUBLE);
+- dt_int = PyArray_DescrFromType(NPY_INT);
+- /* double[2][3] = pv */
+- dtype_def = Py_BuildValue("[(s, s), (s, s)]",
+- "p", "(3,)f8", "v", "(3,)f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_pv);
+- Py_DECREF(dtype_def);
+- /* double[2] = pvdpv */
+- dtype_def = Py_BuildValue("[(s, s), (s, s)]",
+- "pdp", "f8", "pdv", "f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_pvdpv);
+- Py_DECREF(dtype_def);
+- /* int[4] = ymdf, hmsf, dmsf */
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "y", "i4", "m", "i4", "d", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_ymdf);
+- Py_DECREF(dtype_def);
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "h", "i4", "m", "i4", "s", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_hmsf);
+- Py_DECREF(dtype_def);
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "h", "i4", "m", "i4", "s", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_dmsf);
+- Py_DECREF(dtype_def);
+- /* char1 (have to use structured, otherwise it cannot be a user type) */
+- dtype_def = Py_BuildValue("[(s, s)]", "sign", "S1");
+- PyArray_DescrAlignConverter(dtype_def, &dt_sign);
+- Py_DECREF(dtype_def);
+- /* char12 */
+- dtype_def = Py_BuildValue("[(s, s)]", "type", "S12");
+- PyArray_DescrAlignConverter(dtype_def, &dt_type);
+- Py_DECREF(dtype_def);
+- /* eraLDBODY */
+- dtype_def = Py_BuildValue(
+- "[(s, s), (s, s), (s, s)]",
+- "bm", "f8", /* mass of the body (solar masses) */
+- "dl", "f8", /* deflection limiter (radians^2/2) */
+- "pv", "(2,3)f8" /* barycentric PV of the body (au, au/day) */
+- );
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraLDBODY);
+- Py_DECREF(dtype_def);
+- /* eraASTROM */
+- dtype_def = Py_BuildValue(
+- "[(s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s), (s, s)]",
+- "pmt", "f8", /* PM time interval (SSB, Julian years) */
+- "eb", "(3,)f8", /* SSB to observer (vector, au) */
+- "eh", "(3,)f8", /* Sun to observer (unit vector) */
+- "em", "f8", /* distance from Sun to observer (au) */
+- "v", "(3,)f8", /* barycentric observer velocity (vector, c) */
+- "bm1", "f8", /* sqrt(1-|v|^2): reciprocal of Lorenz factor */
+- "bpn", "(3,3)f8", /* bias-precession-nutation matrix */
+- "along", "f8", /* longitude + s' + dERA(DUT) (radians) */
+- "phi", "f8", /* geodetic latitude (radians) */
+- "xpl", "f8", /* polar motion xp wrt local meridian (radians) */
+- "ypl", "f8", /* polar motion yp wrt local meridian (radians) */
+- "sphi", "f8", /* sine of geodetic latitude */
+- "cphi", "f8", /* cosine of geodetic latitude */
+- "diurab", "f8", /* magnitude of diurnal aberration vector */
+- "eral", "f8", /* "local" Earth rotation angle (radians) */
+- "refa", "f8", /* refraction constant A (radians) */
+- "refb", "f8" /* refraction constant B (radians) */
+- );
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraASTROM);
+- Py_DECREF(dtype_def);
+- /* eraLEAPSECOND */
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s)]",
+- "year", "i4", "month", "i4", "tai_utc", "f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraLEAPSECOND);
+- Py_DECREF(dtype_def);
+-
+- if (dt_double == NULL || dt_int == NULL ||
+- dt_pv == NULL || dt_pvdpv == NULL ||
+- dt_ymdf == NULL || dt_hmsf == NULL || dt_dmsf == NULL ||
+- dt_sign == NULL || dt_type == NULL ||
+- dt_eraLDBODY == NULL || dt_eraASTROM == NULL ||
+- dt_eraLEAPSECOND == NULL) {
+- goto fail;
+- }
+- /* Make the structured dtypes available in the module */
+- PyDict_SetItemString(d, "dt_pv", (PyObject *)dt_pv);
+- PyDict_SetItemString(d, "dt_pvdpv", (PyObject *)dt_pvdpv);
+- PyDict_SetItemString(d, "dt_ymdf", (PyObject *)dt_ymdf);
+- PyDict_SetItemString(d, "dt_hmsf", (PyObject *)dt_hmsf);
+- PyDict_SetItemString(d, "dt_dmsf", (PyObject *)dt_dmsf);
+- PyDict_SetItemString(d, "dt_sign", (PyObject *)dt_sign);
+- PyDict_SetItemString(d, "dt_type", (PyObject *)dt_type);
+- PyDict_SetItemString(d, "dt_eraLDBODY", (PyObject *)dt_eraLDBODY);
+- PyDict_SetItemString(d, "dt_eraASTROM", (PyObject *)dt_eraASTROM);
+- PyDict_SetItemString(d, "dt_eraLEAPSECOND", (PyObject *)dt_eraLEAPSECOND);
+- /*
+- * Define the ufuncs. For those without structured dtypes,
+- * the ufunc creation uses the static variables defined above;
+- * for those with structured dtypes, an empty ufunc is created,
+- * and then a userloop is added. For both, we set the type
+- * resolver to our own, and then add the ufunc to the module.
+- *
+- * Note that for the arguments, any inout arguments, i.e., those
+- * that are changed in-place in the ERFA function, are repeated,
+- * since we want the ufuncs not to do in-place changes (unless
+- * explicitly requested with ufunc(..., in,..., out=in))
+- */
+- {%- for func in funcs %}
+- {%- if not func.user_dtype %}
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_{{ func.pyname }}, data, types_{{ func.pyname }},
+- 1, {{ func.args_by_inout('in|inout')|count }}, {{ func.args_by_inout('inout|out|ret|stat')|count }}, PyUFunc_None,
+- "{{ func.pyname }}",
+- "UFunc wrapper for {{ func.name }}",
+- 0, {% if func.signature -%} "{{ func.signature }}" {%- else -%} NULL {%- endif -%});
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- {%- else %}
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, {{ func.args_by_inout('in|inout')|count }}, {{ func.args_by_inout('inout|out|ret|stat')|count }}, PyUFunc_None,
+- "{{ func.pyname }}",
+- "UFunc wrapper for {{ func.name }}",
+- 0, {% if func.signature -%} "{{ func.signature }}" {%- else -%} NULL {%- endif -%});
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- {%- for arg in func.args_by_inout('in|inout') %}
+- dtypes[{{ loop.index - 1 }}] = {{ arg.dtype }};
+- {%- endfor %}
+- {%- for arg in func.args_by_inout('inout|out|ret|stat') %}
+- dtypes[{{ loop.index - 1 + func.args_by_inout('in|inout')|count }}] = {{ arg.dtype }};
+- {%- endfor %}
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, {{ func.user_dtype }},
+- ufunc_loop_{{ func.pyname }}, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- {%- endif %}
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "{{ func.pyname }}", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- {%- endfor %}
+-
+- goto decref;
+-
+-fail:
+- Py_XDECREF(m);
+- m = NULL;
+-
+-decref:
+- Py_XDECREF(dt_double);
+- Py_XDECREF(dt_int);
+- Py_XDECREF(dt_pv);
+- Py_XDECREF(dt_pvdpv);
+- Py_XDECREF(dt_ymdf);
+- Py_XDECREF(dt_hmsf);
+- Py_XDECREF(dt_dmsf);
+- Py_XDECREF(dt_sign);
+- Py_XDECREF(dt_type);
+- Py_XDECREF(dt_eraASTROM);
+- Py_XDECREF(dt_eraLDBODY);
+- Py_XDECREF(dt_eraLEAPSECOND);
+- return m;
+-}
+Index: astropy-4.1/astropy/__init__.py
+===================================================================
+--- astropy-4.1.orig/astropy/__init__.py
++++ astropy-4.1/astropy/__init__.py
+@@ -14,6 +14,7 @@ from .version import version as __versio
+
+ __minimum_python_version__ = '3.6'
+ __minimum_numpy_version__ = '1.16.0'
++__minimum_erfa_version__ = '1.7'
+ __minimum_scipy_version__ = '0.18'
+ # ASDF is an optional dependency, but this is the minimum version that is
+ # compatible with Astropy when it is installed.
+@@ -73,32 +74,34 @@ else:
+ online_docs_root = f'https://docs.astropy.org/en/{__version__}/'
+
+
+-def _check_numpy():
++def _check_requirement(name, minimum_version):
+ """
+ Check that Numpy is installed and it is of the minimum version we
+ require.
+ """
+ # Note: We could have used distutils.version for this comparison,
+- # but it seems like overkill to import distutils at runtime.
++ # but it seems like overkill to import distutils at runtime, and
++ # our own utils.introspection.minversion indirectly needs requirements.
+ requirement_met = False
+ import_fail = ''
+ try:
+- import numpy
++ module = __import__(name)
+ except ImportError:
+- import_fail = 'Numpy is not installed.'
++ import_fail = f'{name} is not installed.'
+ else:
+- from .utils import minversion
+- requirement_met = minversion(numpy, __minimum_numpy_version__)
++ version = getattr(module, '__version__')
++ requirement_met = version.split('.') >= minimum_version.split('.')
+
+ if not requirement_met:
+- msg = (f"Numpy version {__minimum_numpy_version__} or later must "
++ msg = (f"{name} version {__minimum_numpy_version__} or later must "
+ f"be installed to use Astropy. {import_fail}")
+ raise ImportError(msg)
+
+- return numpy
++ return module
+
+
+-_check_numpy()
++_check_requirement('numpy', __minimum_numpy_version__)
++_check_requirement('erfa', __minimum_erfa_version__)
+
+
+ from . import config as _config
+Index: astropy-4.1/astropy/tests/tests/test_imports.py
+===================================================================
+--- astropy-4.1.orig/astropy/tests/tests/test_imports.py
++++ astropy-4.1/astropy/tests/tests/test_imports.py
+@@ -1,8 +1,6 @@
+ # Licensed under a 3-clause BSD style license - see LICENSE.rst
+
+ import pkgutil
+-import os
+-import types
+
+
+ def test_imports():
+@@ -10,35 +8,16 @@ def test_imports():
+ This just imports all modules in astropy, making sure they don't have any
+ dependencies that sneak through
+ """
+-
+- from astropy.utils import find_current_module
+-
+- pkgornm = find_current_module(1).__name__.split('.')[0]
+-
+- if isinstance(pkgornm, str):
+- package = pkgutil.get_loader(pkgornm).load_module(pkgornm)
+- elif (isinstance(pkgornm, types.ModuleType) and
+- '__init__' in pkgornm.__file__):
+- package = pkgornm
+- else:
+- msg = 'test_imports is not determining a valid package/package name'
+- raise TypeError(msg)
+-
+- if hasattr(package, '__path__'):
+- pkgpath = package.__path__
+- elif hasattr(package, '__file__'):
+- pkgpath = os.path.split(package.__file__)[0]
+- else:
+- raise AttributeError('package to generate config items for does not '
+- 'have __file__ or __path__')
+-
+- prefix = package.__name__ + '.'
+-
+ def onerror(name):
+- # A legitimate error occurred in a module that wasn't excluded
+- raise
++ # We should raise any legitimate error that occurred, but not
++ # any warnings which happen to be caught because of our pytest
++ # settings (e.g., DeprecationWarning).
++ try:
++ raise
++ except Warning:
++ pass
+
+- for imper, nm, ispkg in pkgutil.walk_packages(pkgpath, prefix,
++ for imper, nm, ispkg in pkgutil.walk_packages(['astropy'], 'astropy.',
+ onerror=onerror):
+ imper.find_module(nm)
+
+Index: astropy-4.1/astropy/time/core.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/core.py
++++ astropy-4.1/astropy/time/core.py
+@@ -15,9 +15,9 @@ from time import strftime
+ from warnings import warn
+
+ import numpy as np
++import erfa
+
+ from astropy import units as u, constants as const
+-from astropy import _erfa as erfa
+ from astropy.units import UnitConversionError
+ from astropy.utils import ShapedLikeNDArray
+ from astropy.utils.compat.misc import override__dir__
+Index: astropy-4.1/astropy/time/formats.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/formats.py
++++ astropy-4.1/astropy/time/formats.py
+@@ -9,11 +9,11 @@ from decimal import Decimal
+ from collections import OrderedDict, defaultdict
+
+ import numpy as np
++import erfa
+
+ from astropy.utils.decorators import lazyproperty
+ from astropy.utils.exceptions import AstropyDeprecationWarning
+ from astropy import units as u
+-from astropy import _erfa as erfa
+
+ from . import utils
+ from .utils import day_frac, quantity_day_frac, two_sum, two_product
+Index: astropy-4.1/astropy/time/tests/test_basic.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/tests/test_basic.py
++++ astropy-4.1/astropy/time/tests/test_basic.py
+@@ -9,6 +9,7 @@ from decimal import Decimal, localcontex
+
+ import numpy as np
+ from numpy.testing import assert_allclose
++import erfa
+
+ from astropy.tests.helper import catch_warnings, pytest
+ from astropy.utils.exceptions import AstropyDeprecationWarning, ErfaWarning
+@@ -17,7 +18,6 @@ from astropy.time import (Time, TimeDelt
+ TimeString, TimezoneInfo, TIME_FORMATS)
+ from astropy.coordinates import EarthLocation
+ from astropy import units as u
+-from astropy import _erfa as erfa
+ from astropy.table import Column, Table
+
+ try:
+Index: astropy-4.1/astropy/time/tests/test_custom_formats.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/tests/test_custom_formats.py
++++ astropy-4.1/astropy/time/tests/test_custom_formats.py
+@@ -6,8 +6,8 @@ from itertools import count
+ import pytest
+
+ import numpy as np
++from erfa import DJM0
+
+-from astropy._erfa import DJM0
+ from astropy.time import Time, TimeFormat
+ from astropy.time.utils import day_frac
+
+Index: astropy-4.1/astropy/time/tests/test_precision.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/tests/test_precision.py
++++ astropy-4.1/astropy/time/tests/test_precision.py
+@@ -2,6 +2,7 @@ import decimal
+ import warnings
+ import functools
+ import contextlib
++import erfa
+ from decimal import Decimal
+ from datetime import datetime, timedelta
+
+@@ -13,7 +14,6 @@ from hypothesis.strategies import (compo
+
+ import numpy as np
+
+-import astropy._erfa as erfa
+ import astropy.units as u
+ from astropy.tests.helper import assert_quantity_allclose
+ from astropy.time import STANDARD_TIME_SCALES, Time, TimeDelta
+Index: astropy-4.1/astropy/time/tests/test_update_leap_seconds.py
+===================================================================
+--- astropy-4.1.orig/astropy/time/tests/test_update_leap_seconds.py
++++ astropy-4.1/astropy/time/tests/test_update_leap_seconds.py
+@@ -2,8 +2,8 @@
+ from datetime import datetime, timedelta
+
+ import pytest
++import erfa
+
+-from astropy import _erfa as erfa
+ from astropy.utils import iers
+ from astropy.utils.exceptions import AstropyWarning
+
+Index: astropy-4.1/astropy/units/quantity_helper/erfa.py
+===================================================================
+--- astropy-4.1.orig/astropy/units/quantity_helper/erfa.py
++++ astropy-4.1/astropy/units/quantity_helper/erfa.py
+@@ -2,6 +2,7 @@
+ # Licensed under a 3-clause BSD style license - see LICENSE.rst
+ """Quantity helpers for the ERFA ufuncs."""
+
++from erfa import ufunc as erfa_ufunc
+
+ from astropy.units.core import UnitsError, UnitTypeError, dimensionless_unscaled
+ from . import UFUNC_HELPERS
+@@ -44,8 +45,6 @@ def helper_p2s(f, unit1):
+
+
+ def get_erfa_helpers():
+- from astropy._erfa import ufunc as erfa_ufunc
+-
+ ERFA_HELPERS = {}
+ ERFA_HELPERS[erfa_ufunc.s2c] = helper_s2c
+ ERFA_HELPERS[erfa_ufunc.s2p] = helper_s2p
+@@ -58,5 +57,5 @@ def get_erfa_helpers():
+ return ERFA_HELPERS
+
+
+-UFUNC_HELPERS.register_module('astropy._erfa.ufunc', erfa_ufuncs,
++UFUNC_HELPERS.register_module('erfa.ufunc', erfa_ufuncs,
+ get_erfa_helpers)
+Index: astropy-4.1/astropy/units/tests/test_quantity_ufuncs.py
+===================================================================
+--- astropy-4.1.orig/astropy/units/tests/test_quantity_ufuncs.py
++++ astropy-4.1/astropy/units/tests/test_quantity_ufuncs.py
+@@ -8,10 +8,10 @@ from collections import namedtuple
+ import pytest
+ import numpy as np
+ from numpy.testing import assert_allclose
++from erfa import ufunc as erfa_ufunc
+
+ from astropy import units as u
+ from astropy.units import quantity_helper as qh
+-from astropy._erfa import ufunc as erfa_ufunc
+ from astropy.tests.helper import raises, catch_warnings
+ from astropy.utils.compat.context import nullcontext
+
+Index: astropy-4.1/astropy/utils/exceptions.py
+===================================================================
+--- astropy-4.1.orig/astropy/utils/exceptions.py
++++ astropy-4.1/astropy/utils/exceptions.py
+@@ -2,10 +2,24 @@
+ """
+ This module contains errors/exceptions and warnings of general use for
+ astropy. Exceptions that are specific to a given subpackage should *not* be
+-here, but rather in the particular subpackage. Exception is the _erfa module
+-as we rather have the users import those exceptions from here.
++here, but rather in the particular subpackage.
+ """
+
++# TODO: deprecate these. This cannot be trivially done with
++# astropy.utils.decorators.deprecate, since that module needs the exceptions
++# here, leading to circular import problems.
++from erfa import ErfaError, ErfaWarning # noqa
++
++
++__all__ = [
++ 'AstropyWarning',
++ 'AstropyUserWarning',
++ 'AstropyDeprecationWarning',
++ 'AstropyPendingDeprecationWarning',
++ 'AstropyBackwardsIncompatibleChangeWarning',
++ 'DuplicateRepresentationWarning',
++ 'NoValue']
++
+
+ class AstropyWarning(Warning):
+ """
+@@ -51,28 +65,6 @@ class DuplicateRepresentationWarning(Ast
+ """
+
+
+-class ErfaError(ValueError):
+- """
+- A class for errors triggered by ERFA functions (status codes < 0)
+-
+- Note: this class should *not* be referenced by fully-qualified name, because
+- it may move to ERFA in a future version. In a future such move it will
+- still be imported here as an alias, but the true namespace of the class may
+- change.
+- """
+-
+-
+-class ErfaWarning(AstropyUserWarning):
+- """
+- A class for warnings triggered by ERFA functions (status codes > 0)
+-
+- Note: this class should *not* be referenced by fully-qualified name, because
+- it may move to ERFA in a future version. In a future such move it will
+- still be imported here as an alias, but the true namespace of the class may
+- change.
+- """
+-
+-
+ class _NoValue:
+ """Special keyword value.
+
+Index: astropy-4.1/astropy/utils/iers/iers.py
+===================================================================
+--- astropy-4.1.orig/astropy/utils/iers/iers.py
++++ astropy-4.1/astropy/utils/iers/iers.py
+@@ -15,9 +15,9 @@ from warnings import warn
+ from urllib.parse import urlparse
+
+ import numpy as np
++import erfa
+
+ from astropy.time import Time, TimeDelta
+-from astropy import _erfa as erfa
+ from astropy import config as _config
+ from astropy import units as u
+ from astropy.table import QTable, MaskedColumn
+Index: astropy-4.1/astropy/utils/iers/tests/test_leap_second.py
+===================================================================
+--- astropy-4.1.orig/astropy/utils/iers/tests/test_leap_second.py
++++ astropy-4.1/astropy/utils/iers/tests/test_leap_second.py
+@@ -5,8 +5,8 @@ import os
+ import pytest
+ import numpy as np
+ from numpy.testing import assert_array_equal
++import erfa
+
+-from astropy import _erfa as erfa
+ from astropy.time import Time, TimeDelta
+ from astropy.utils.iers import iers
+ from astropy.utils.data import get_pkg_data_filename
+Index: astropy-4.1/conftest.py
+===================================================================
+--- astropy-4.1.orig/conftest.py
++++ astropy-4.1/conftest.py
+@@ -10,6 +10,7 @@ import hypothesis
+
+ try:
+ from pytest_astropy_header.display import PYTEST_HEADER_MODULES
++ PYTEST_HEADER_MODULES['PyERFA'] = 'erfa'
+ except ImportError:
+ PYTEST_HEADER_MODULES = {}
+
+Index: astropy-4.1/docs/conf.py
+===================================================================
+--- astropy-4.1.orig/docs/conf.py
++++ astropy-4.1/docs/conf.py
+@@ -68,6 +68,7 @@ check_sphinx_version("1.2.1")
+ del intersphinx_mapping['astropy']
+
+ # add any custom intersphinx for astropy
++intersphinx_mapping['pyerfa'] = ('https://pyerfa.readthedocs.io/en/stable/', None)
+ intersphinx_mapping['pytest'] = ('https://pytest.readthedocs.io/en/stable/', None)
+ intersphinx_mapping['ipython'] = ('https://ipython.readthedocs.io/en/stable/', None)
+ intersphinx_mapping['pandas'] = ('https://pandas.pydata.org/pandas-docs/stable/', None)
+@@ -91,6 +92,7 @@ templates_path.append('_templates')
+ rst_epilog += """
+ .. |minimum_python_version| replace:: {0.__minimum_python_version__}
+ .. |minimum_numpy_version| replace:: {0.__minimum_numpy_version__}
++.. |minimum_erfa_version| replace:: {0.__minimum_erfa_version__}
+ .. |minimum_scipy_version| replace:: {0.__minimum_scipy_version__}
+ .. |minimum_yaml_version| replace:: {0.__minimum_yaml_version__}
+ .. |minimum_asdf_version| replace:: {0.__minimum_asdf_version__}
+Index: astropy-4.1/docs/coordinates/references.txt
+===================================================================
+--- astropy-4.1.orig/docs/coordinates/references.txt
++++ astropy-4.1/docs/coordinates/references.txt
+@@ -6,3 +6,5 @@
+ .. |Latitude| replace:: `~astropy.coordinates.Latitude`
+ .. |baseframe| replace:: `~astropy.coordinates.BaseCoordinateFrame`
+ .. |earthlocation| replace:: `~astropy.coordinates.EarthLocation`
++.. _ERFA: https://github.com/liberfa/erfa
++.. _PyERFA: https://github.com/liberfa/pyerfa
+Index: astropy-4.1/docs/coordinates/solarsystem.rst
+===================================================================
+--- astropy-4.1.orig/docs/coordinates/solarsystem.rst
++++ astropy-4.1/docs/coordinates/solarsystem.rst
+@@ -7,7 +7,7 @@ Solar System Ephemerides
+
+ `astropy.coordinates` can calculate the |SkyCoord| of some of the major solar
+ system objects. By default, it uses approximate orbital elements calculated
+-using built-in `ERFA `_ routines, but it can
++using PyERFA_ routines, but it can
+ also use more precise ones using the JPL ephemerides (which are derived from
+ dynamical models). The default JPL ephemerides (DE430) provide predictions
+ valid roughly for the years between 1550 and 2650. The file is 115 MB and will
+@@ -137,15 +137,12 @@ Precision of the Built-In Ephemeris
+ ===================================
+
+ The algorithm for calculating positions and velocities for planets other than
+-Earth used by ERFA_ is due to J.L. Simon, P. Bretagnon, J. Chapront,
++Earth used by ERFA is due to J.L. Simon, P. Bretagnon, J. Chapront,
+ M. Chapront-Touze, G. Francou and J. Laskar (Bureau des Longitudes, Paris,
+ France). From comparisons with JPL ephemeris DE102, they quote the maximum
+-errors over the interval 1800-2050 below. For more details see
+-`cextern/erfa/plan94.c
+-`_.
++errors over the interval 1800-2050 below. For more details see `erfa.plan94`
+ For the Earth, the rms errors in position and velocity are about 4.6 km and
+-1.4 mm/s, respectively (see `cextern/erfa/epv00.c
+-`_).
++1.4 mm/s, respectively `erfa.epv00`.
+
+ .. list-table::
+
+Index: astropy-4.1/docs/development/workflow/known_projects.inc
+===================================================================
+--- astropy-4.1.orig/docs/development/workflow/known_projects.inc
++++ astropy-4.1/docs/development/workflow/known_projects.inc
+@@ -10,6 +10,10 @@
+ .. _`numpy github`: https://github.com/numpy/numpy
+ .. _`numpy mailing list`: http://mail.python.org/mailman/listinfo/numpy-discussion
+
++.. pyerfa
++.. _pyerfa: http://pyerfa.readthedocs.org/
++.. _`pyerfa github`: https://github.com/liberfa/pyerfa/
++
+ .. scipy
+ .. _scipy: https://www.scipy.org/
+ .. _`scipy github`: https://github.com/scipy/scipy
+Index: astropy-4.1/docs/install.rst
+===================================================================
+--- astropy-4.1.orig/docs/install.rst
++++ astropy-4.1/docs/install.rst
+@@ -13,6 +13,8 @@ Requirements
+
+ - `Numpy`_ |minimum_numpy_version| or later
+
++- `PyERFA`_ |minimum_erfa_version| or later
++
+ ``astropy`` also depends on other packages for optional features:
+
+ - `scipy`_ |minimum_scipy_version| or later: To power a variety of features
+@@ -343,9 +345,6 @@ The C libraries currently bundled with `
+ ``cextern/cfitsio/changes.txt`` for the bundled version. To use the
+ system version, set ``ASTROPY_USE_SYSTEM_CFITSIO=1``.
+
+-- `erfa `_ see ``cextern/erfa/README.rst`` for the
+- bundled version. To use the system version, set ``ASTROPY_USE_SYSTEM_ERFA=1``.
+-
+ - `expat `_ see ``cextern/expat/README`` for the
+ bundled version. To use the system version, set ``ASTROPY_USE_SYSTEM_EXPAT=1``.
+
+Index: astropy-4.1/docs/known_issues.rst
+===================================================================
+--- astropy-4.1.orig/docs/known_issues.rst
++++ astropy-4.1/docs/known_issues.rst
+@@ -319,42 +319,6 @@ If so, you can go ahead and try running
+ terminal).
+
+
+-Creating a Time Object Fails with ValueError After Upgrading ``astropy``
+-------------------------------------------------------------------------
+-
+-In some cases, when users have upgraded ``astropy`` from an older version to v1.0
+-or greater, they have run into the following crash when trying to create an
+-`~astropy.time.Time` object::
+-
+- >>> from astropy.time import Time
+- >>> datetime = Time('2012-03-01T13:08:00', scale='utc') # doctest: +SKIP
+- Traceback (most recent call last):
+- ...
+- ValueError: Input values did not match any of the formats where
+- the format keyword is optional [u'astropy_time', u'datetime',
+- u'jyear_str', u'iso', u'isot', u'yday', u'byear_str']
+-
+-This problem can occur when there is a version mismatch between the compiled
+-ERFA library (included as part of ``astropy`` in most distributions), and
+-the version of the ``astropy`` Python source.
+-
+-This can be from a number of causes. The most likely is that when installing the
+-new ``astropy`` version, your previous ``astropy`` version was not fully uninstalled
+-first, resulting in a mishmash of versions. Your best bet is to fully remove
+-``astropy`` from its installation path and reinstall from scratch using your
+-preferred installation method. Removing the old version may be achieved by
+-removing the entire ``astropy/`` directory from within the
+-``site-packages`` directory it is installed in. However, if in doubt, ask
+-how best to uninstall packages from your preferred Python distribution.
+-
+-Another possible cause of this error, in particular for people developing on
+-Astropy and installing from a source checkout, is that your Astropy build
+-directory is unclean. To fix this, run ``git clean -dfx``. This removes
+-*all* build artifacts from the repository that aren't normally tracked by git.
+-Make sure before running this that there are no untracked files in the
+-repository you intend to save. Then rebuild/reinstall from the clean repo.
+-
+-
+ Failing Logging Tests When Running the Tests in IPython
+ -------------------------------------------------------
+
+Index: astropy-4.1/docs/time/index.rst
+===================================================================
+--- astropy-4.1.orig/docs/time/index.rst
++++ astropy-4.1/docs/time/index.rst
+@@ -19,7 +19,7 @@ dates. Specific emphasis is placed on su
+ UT1, TDB) and time representations (e.g., JD, MJD, ISO 8601) that are used in
+ astronomy and required to calculate, for example, sidereal times and barycentric
+ corrections. The `astropy.time` package is based on fast and memory efficient
+-wrappers around the `ERFA`_ time and calendar routines.
++PyERFA_ wrappers around the ERFA_ time and calendar routines.
+
+ All time manipulations and arithmetic operations are done internally using two
+ 64-bit floats to represent time. Floating point algorithms from [#]_ are used so
+@@ -362,7 +362,7 @@ local Local Time Scale (LOCAL)
+ ====== =================================
+
+ .. [#] Wikipedia `time standard `_ article
+-.. [#] SOFA Time Scale and Calendar Tools
++.. [#] SOFA_ Time Scale and Calendar Tools
+ `(PDF) `_
+ .. [#] ``_
+
+@@ -506,7 +506,7 @@ requiring no better than microsecond pre
+ years) can safely ignore the internal representation details and skip this
+ section.
+
+-This representation is driven by the underlying ERFA C-library implementation.
++This representation is driven by the underlying ERFA_ C-library implementation.
+ The ERFA routines take care throughout to maintain overall precision of the
+ double pair. Users are free to choose the way in which total JD is
+ provided, though internally one part contains integer days and the
+@@ -606,7 +606,7 @@ precision
+ The ``precision`` setting affects string formats when outputting a value that
+ includes seconds. It must be an integer between 0 and 9. There is no effect
+ when inputting time values from strings. The default precision is 3. Note
+-that the limit of 9 digits is driven by the way that ERFA handles fractional
++that the limit of 9 digits is driven by the way that ERFA_ handles fractional
+ seconds. In practice this should should not be an issue. ::
+
+ >>> t = Time('B1950.0', precision=3)
+@@ -670,7 +670,7 @@ This optional parameter specifies the ob
+ either a tuple with geocentric coordinates (X, Y, Z), or a tuple with geodetic
+ coordinates (longitude, latitude, height; with height defaulting to zero).
+ They are used for time scales that are sensitive to observer location
+-(currently, only TDB, which relies on the ERFA routine ``eraDtdb`` to
++(currently, only TDB, which relies on the PyERFA_ routine `erfa.dtdb` to
+ determine the time offset between TDB and TT), as well as for sidereal time if
+ no explicit longitude is given.
+
+@@ -964,7 +964,7 @@ Transformation Offsets
+
+ Time scale transformations that cross one of the orange circles in the image
+ above require an additional offset time value that is model or
+-observation dependent. See `SOFA Time Scale and Calendar Tools
++observation dependent. See SOFA_ `Time Scale and Calendar Tools
+ `_ for further details.
+
+ The two attributes :attr:`~astropy.time.Time.delta_ut1_utc` and
+@@ -1010,7 +1010,7 @@ scale along with the auto-download featu
+ In the case of the TDB to TT offset, most users need only provide the ``lon``
+ and ``lat`` values when creating the |Time| object. If the
+ :attr:`~astropy.time.Time.delta_tdb_tt` attribute is not explicitly set, then
+-the ERFA C-library routine ``eraDtdb`` will be used to compute the TDB to TT
++the PyERFA_ routine `erfa.dtdb` will be used to compute the TDB to TT
+ offset. Note that if ``lon`` and ``lat`` are not explicitly initialized,
+ values of 0.0 degrees for both will be used.
+
+@@ -1019,7 +1019,7 @@ Example
+
+ .. EXAMPLE START: Transformation Offsets in Time Objects
+
+-The following code replicates an example in the `SOFA Time Scale and Calendar
++The following code replicates an example in the SOFA_ `Time Scale and Calendar
+ Tools `_ document. It does the transform
+ from UTC to all supported time scales (TAI, TCB, TCG, TDB, TT, UT1, UTC). This
+ requires an observer location (here, latitude and longitude).
+@@ -1082,7 +1082,7 @@ Apparent or mean sidereal time can be ca
+ :meth:`~astropy.time.Time.sidereal_time`. The method returns a |Longitude|
+ with units of hour angle, which by default is for the longitude corresponding to
+ the location with which the |Time| object is initialized. Like the scale
+-transformations, ERFA C-library routines are used under the hood, which support
++transformations, ERFA_ C-library routines are used under the hood, which support
+ calculations following different IAU resolutions.
+
+ Example
+@@ -1311,7 +1311,7 @@ the TDB timescale::
+ .. EXAMPLE START: Calculating Light Travel Time Using JPL Ephemerides
+
+ By default, the light travel time is calculated using the position and velocity
+-of Earth and the Sun from built-in `ERFA `_
++of Earth and the Sun from ERFA_
+ routines, but you can also get more precise calculations using the JPL
+ ephemerides (which are derived from dynamical models). An example using the JPL
+ ephemerides is:
+@@ -1588,11 +1588,10 @@ Reference/API
+ Acknowledgments and Licenses
+ ============================
+
+-This package makes use of the `ERFA Software
+-`_ ANSI C library. The copyright of the ERFA
++This package makes use of the PyERFA_ wrappers of the ERFA_ ANSI C library. The copyright of the ERFA_
+ software belongs to the NumFOCUS Foundation. The library is made available
+ under the terms of the "BSD-three clauses" license.
+
+-The ERFA library is derived, with permission, from the International
+-Astronomical Union's "Standards of Fundamental Astronomy" library,
++The ERFA_ library is derived, with permission, from the International
++Astronomical Union's "Standards of Fundamental Astronomy" (SOFA_) library,
+ available from http://www.iausofa.org.
+Index: astropy-4.1/docs/time/references.txt
+===================================================================
+--- astropy-4.1.orig/docs/time/references.txt
++++ astropy-4.1/docs/time/references.txt
+@@ -2,3 +2,4 @@
+ .. |TimeDelta| replace:: :class:`~astropy.time.TimeDelta`
+ .. _SOFA: http://www.iausofa.org/index.html
+ .. _ERFA: https://github.com/liberfa/erfa
++.. _PyERFA: https://github.com/liberfa/pyerfa
+Index: astropy-4.1/setup.cfg
+===================================================================
+--- astropy-4.1.orig/setup.cfg
++++ astropy-4.1/setup.cfg
+@@ -21,11 +21,15 @@ classifiers =
+
+ [options]
+ packages = find:
+-requires = numpy
++requires =
++ numpy
++ pyerfa
+ zip_safe = False
+ tests_require = pytest-astropy
+ setup_requires = setuptools_scm
+-install_requires = numpy>=1.16
++install_requires =
++ numpy>=1.16
++ pyerfa
+ python_requires = >=3.6
+
+ [options.packages.find]
+Index: astropy-4.1/astropy/_erfa/core.py
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/core.py
++++ /dev/null
+@@ -1,20342 +0,0 @@
+-# Licensed under a 3-clause BSD style license - see LICENSE.rst
+-
+-# "core.py" is auto-generated by erfa_generator.py from the template
+-# "core.py.templ". Do *not* edit "core.py" directly, instead edit
+-# "core.py.templ" and run erfa_generator.py from the source directory to
+-# update it.
+-
+-"""
+-Python wrappers for the ufunc wrappers of the ERFA library.
+-
+-..warning::
+- This is currently *not* part of the public Astropy API, and may change in
+- the future.
+-
+-The key idea is that any function can be called with inputs that are arrays,
+-and the ufuncs will automatically vectorize and call the ERFA functions for
+-each item using broadcasting rules for numpy. So the return values are always
+-numpy arrays of some sort.
+-
+-For ERFA functions that take/return vectors or matrices, the vector/matrix
+-dimension(s) are always the *last* dimension(s). For example, if you
+-want to give ten matrices (i.e., the ERFA input type is double[3][3]),
+-you would pass in a (10, 3, 3) numpy array. If the output of the ERFA
+-function is scalar, you'll get back a length-10 1D array.
+-(Note that the ufuncs take this into account using structured dtypes.)
+-
+-Note that the ufunc part of these functions are implemented in a separate
+-module (compiled as ``ufunc``), derived from the ``ufunc.c`` file.
+-"""
+-
+-import warnings
+-
+-import numpy
+-
+-# we import these exceptions from astropy locations instead of defining them
+-# in this file because otherwise there are circular dependencies
+-from astropy.utils.exceptions import ErfaError, ErfaWarning
+-from astropy.utils.misc import check_broadcast
+-
+-from . import ufunc
+-
+-__all__ = ['ErfaError', 'ErfaWarning',
+- 'cal2jd', 'epb', 'epb2jd', 'epj', 'epj2jd', 'jd2cal', 'jdcalf', 'ab', 'apcg', 'apcg13', 'apci', 'apci13', 'apco', 'apco13', 'apcs', 'apcs13', 'aper', 'aper13', 'apio', 'apio13', 'atci13', 'atciq', 'atciqn', 'atciqz', 'atco13', 'atic13', 'aticq', 'aticqn', 'atio13', 'atioq', 'atoc13', 'atoi13', 'atoiq', 'ld', 'ldn', 'ldsun', 'pmpx', 'pmsafe', 'pvtob', 'refco', 'epv00', 'plan94', 'fad03', 'fae03', 'faf03', 'faju03', 'fal03', 'falp03', 'fama03', 'fame03', 'fane03', 'faom03', 'fapa03', 'fasa03', 'faur03', 'fave03', 'bi00', 'bp00', 'bp06', 'bpn2xy', 'c2i00a', 'c2i00b', 'c2i06a', 'c2ibpn', 'c2ixy', 'c2ixys', 'c2t00a', 'c2t00b', 'c2t06a', 'c2tcio', 'c2teqx', 'c2tpe', 'c2txy', 'eo06a', 'eors', 'fw2m', 'fw2xy', 'ltp', 'ltpb', 'ltpecl', 'ltpequ', 'num00a', 'num00b', 'num06a', 'numat', 'nut00a', 'nut00b', 'nut06a', 'nut80', 'nutm80', 'obl06', 'obl80', 'p06e', 'pb06', 'pfw06', 'pmat00', 'pmat06', 'pmat76', 'pn00', 'pn00a', 'pn00b', 'pn06', 'pn06a', 'pnm00a', 'pnm00b', 'pnm06a', 'pnm80', 'pom00', 'pr00', 'prec76', 's00', 's00a', 's00b', 's06', 's06a', 'sp00', 'xy06', 'xys00a', 'xys00b', 'xys06a', 'ee00', 'ee00a', 'ee00b', 'ee06a', 'eect00', 'eqeq94', 'era00', 'gmst00', 'gmst06', 'gmst82', 'gst00a', 'gst00b', 'gst06', 'gst06a', 'gst94', 'pvstar', 'starpv', 'fk425', 'fk45z', 'fk524', 'fk52h', 'fk54z', 'fk5hip', 'fk5hz', 'h2fk5', 'hfk5z', 'starpm', 'eceq06', 'ecm06', 'eqec06', 'lteceq', 'ltecm', 'lteqec', 'g2icrs', 'icrs2g', 'eform', 'gc2gd', 'gc2gde', 'gd2gc', 'gd2gce', 'd2dtf', 'dat', 'dtdb', 'dtf2d', 'taitt', 'taiut1', 'taiutc', 'tcbtdb', 'tcgtt', 'tdbtcb', 'tdbtt', 'tttai', 'tttcg', 'tttdb', 'ttut1', 'ut1tai', 'ut1tt', 'ut1utc', 'utctai', 'utcut1', 'ae2hd', 'hd2ae', 'hd2pa', 'tpors', 'tporv', 'tpsts', 'tpstv', 'tpxes', 'tpxev', 'a2af', 'a2tf', 'af2a', 'anp', 'anpm', 'd2tf', 'tf2a', 'tf2d', 'rx', 'ry', 'rz', 'cp', 'cpv', 'cr', 'p2pv', 'pv2p', 'ir', 'zp', 'zpv', 'zr', 'rxr', 'tr', 'rxp', 'rxpv', 'trxp', 'trxpv', 'rm2v', 'rv2m', 'pap', 'pas', 'sepp', 'seps', 'c2s', 'p2s', 'pv2s', 's2c', 's2p', 's2pv', 'pdp', 'pm', 'pmp', 'pn', 'ppp', 'ppsp', 'pvdpv', 'pvm', 'pvmpv', 'pvppv', 'pvu', 'pvup', 'pvxpv', 'pxp', 's2xpv', 'sxp', 'sxpv', 'pav2pv', 'pv2pav',
+- 'DPI', 'D2PI', 'DR2D', 'DD2R', 'DR2AS', 'DAS2R', 'DS2R', 'TURNAS', 'DMAS2R', 'DTY', 'DAYSEC', 'DJY', 'DJC', 'DJM', 'DJ00', 'DJM0', 'DJM00', 'DJM77', 'TTMTAI', 'DAU', 'CMPS', 'AULT', 'DC', 'ELG', 'ELB', 'TDB0', 'SRS', 'WGS84', 'GRS80', 'WGS72',
+- # TODO: delete the functions below when they can get auto-generated
+- 'version', 'version_major', 'version_minor', 'version_micro', 'sofa_version']
+-
+-
+-# <---------------------------------Error-handling---------------------------->
+-
+-
+-STATUS_CODES = {} # populated below before each function that returns an int
+-
+-# This is a hard-coded list of status codes that need to be remapped,
+-# such as to turn errors into warnings.
+-STATUS_CODES_REMAP = {
+- 'cal2jd': {-3: 3}
+-}
+-
+-
+-def check_errwarn(statcodes, func_name):
+- if not numpy.any(statcodes):
+- return
+- # Remap any errors into warnings in the STATUS_CODES_REMAP dict.
+- if func_name in STATUS_CODES_REMAP:
+- for before, after in STATUS_CODES_REMAP[func_name].items():
+- statcodes[statcodes == before] = after
+- STATUS_CODES[func_name][after] = STATUS_CODES[func_name][before]
+-
+- if numpy.any(statcodes<0):
+- # errors present - only report the errors.
+- if statcodes.shape:
+- statcodes = statcodes[statcodes<0]
+-
+- errcodes = numpy.unique(statcodes)
+-
+- errcounts = dict([(e, numpy.sum(statcodes==e)) for e in errcodes])
+-
+- elsemsg = STATUS_CODES[func_name].get('else', None)
+- if elsemsg is None:
+- errmsgs = dict([(e, STATUS_CODES[func_name].get(e, 'Return code ' + str(e))) for e in errcodes])
+- else:
+- errmsgs = dict([(e, STATUS_CODES[func_name].get(e, elsemsg)) for e in errcodes])
+-
+- emsg = ', '.join(['{0} of "{1}"'.format(errcounts[e], errmsgs[e]) for e in errcodes])
+- raise ErfaError('ERFA function "' + func_name + '" yielded ' + emsg)
+-
+- elif numpy.any(statcodes>0):
+- #only warnings present
+- if statcodes.shape:
+- statcodes = statcodes[statcodes>0]
+-
+- warncodes = numpy.unique(statcodes)
+-
+- warncounts = dict([(w, numpy.sum(statcodes==w)) for w in warncodes])
+-
+- elsemsg = STATUS_CODES[func_name].get('else', None)
+- if elsemsg is None:
+- warnmsgs = dict([(w, STATUS_CODES[func_name].get(w, 'Return code ' + str(w))) for w in warncodes])
+- else:
+- warnmsgs = dict([(w, STATUS_CODES[func_name].get(w, elsemsg)) for w in warncodes])
+-
+- wmsg = ', '.join(['{0} of "{1}"'.format(warncounts[w], warnmsgs[w]) for w in warncodes])
+- warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
+-
+-
+-# <------------------------structured dtype conversion------------------------>
+-
+-dt_bytes1 = numpy.dtype('S1')
+-dt_bytes12 = numpy.dtype('S12')
+-
+-# <--------------------------Actual ERFA-wrapping code------------------------>
+-
+-
+-DPI = (3.141592653589793238462643)
+-"""Pi"""
+-D2PI = (6.283185307179586476925287)
+-"""2Pi"""
+-DR2D = (57.29577951308232087679815)
+-"""Radians to degrees"""
+-DD2R = (1.745329251994329576923691e-2)
+-"""Degrees to radians"""
+-DR2AS = (206264.8062470963551564734)
+-"""Radians to arcseconds"""
+-DAS2R = (4.848136811095359935899141e-6)
+-"""Arcseconds to radians"""
+-DS2R = (7.272205216643039903848712e-5)
+-"""Seconds of time to radians"""
+-TURNAS = (1296000.0)
+-"""Arcseconds in a full circle"""
+-DMAS2R = (DAS2R / 1e3)
+-"""Milliarcseconds to radians"""
+-DTY = (365.242198781)
+-"""Length of tropical year B1900 (days)"""
+-DAYSEC = (86400.0)
+-"""Seconds per day."""
+-DJY = (365.25)
+-"""Days per Julian year"""
+-DJC = (36525.0)
+-"""Days per Julian century"""
+-DJM = (365250.0)
+-"""Days per Julian millennium"""
+-DJ00 = (2451545.0)
+-"""Reference epoch (J2000.0), Julian Date"""
+-DJM0 = (2400000.5)
+-"""Julian Date of Modified Julian Date zero"""
+-DJM00 = (51544.5)
+-"""Reference epoch (J2000.0), Modified Julian Date"""
+-DJM77 = (43144.0)
+-"""1977 Jan 1.0 as MJD"""
+-TTMTAI = (32.184)
+-"""TT minus TAI (s)"""
+-DAU = (149597870.7e3)
+-"""Astronomical unit (m, IAU 2012)"""
+-CMPS = 299792458.0
+-"""Speed of light (m/s)"""
+-AULT = (DAU/CMPS)
+-"""Light time for 1 au (s)"""
+-DC = (DAYSEC/AULT)
+-"""Speed of light (au per day)"""
+-ELG = (6.969290134e-10)
+-"""L_G = 1 - d(TT)/d(TCG)"""
+-ELB = (1.550519768e-8)
+-"""L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0"""
+-TDB0 = (-6.55e-5)
+-"""L_B = 1 - d(TDB)/d(TCB), and TDB (s) at TAI 1977/1/1.0"""
+-SRS = 1.97412574336e-8
+-"""Schwarzschild radius of the Sun (au) = 2 * 1.32712440041e20 / (2.99792458e8)^2 / 1.49597870700e11"""
+-WGS84 = 1
+-"""Reference ellipsoids"""
+-GRS80 = 2
+-"""Reference ellipsoids"""
+-WGS72 = 3
+-"""Reference ellipsoids"""
+-
+-
+-def cal2jd(iy, im, id):
+- """
+- Wrapper for ERFA function ``eraCal2jd``.
+-
+- Parameters
+- ----------
+- iy : int array
+- im : int array
+- id : int array
+-
+- Returns
+- -------
+- djm0 : double array
+- djm : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C a l 2 j d
+- - - - - - - - - - -
+-
+- Gregorian Calendar to Julian Date.
+-
+- Given:
+- iy,im,id int year, month, day in Gregorian calendar (Note 1)
+-
+- Returned:
+- djm0 double MJD zero-point: always 2400000.5
+- djm double Modified Julian Date for 0 hrs
+-
+- Returned (function value):
+- int status:
+- 0 = OK
+- -1 = bad year (Note 3: JD not computed)
+- -2 = bad month (JD not computed)
+- -3 = bad day (JD computed)
+-
+- Notes:
+-
+- 1) The algorithm used is valid from -4800 March 1, but this
+- implementation rejects dates before -4799 January 1.
+-
+- 2) The Julian Date is returned in two pieces, in the usual ERFA
+- manner, which is designed to preserve time resolution. The
+- Julian Date is available as a single number by adding djm0 and
+- djm.
+-
+- 3) In early eras the conversion is from the "Proleptic Gregorian
+- Calendar"; no account is taken of the date(s) of adoption of
+- the Gregorian Calendar, nor is the AD/BC numbering convention
+- observed.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 12.92 (p604).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- djm0, djm, c_retval = ufunc.cal2jd(iy, im, id)
+- check_errwarn(c_retval, 'cal2jd')
+- return djm0, djm
+-
+-
+-STATUS_CODES['cal2jd'] = {0: 'OK', -1: 'bad year (Note 3: JD not computed)', -2: 'bad month (JD not computed)', -3: 'bad day (JD computed)'}
+-
+-
+-def epb(dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraEpb``.
+-
+- Parameters
+- ----------
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a E p b
+- - - - - - - -
+-
+- Julian Date to Besselian Epoch.
+-
+- Given:
+- dj1,dj2 double Julian Date (see note)
+-
+- Returned (function value):
+- double Besselian Epoch.
+-
+- Note:
+-
+- The Julian Date is supplied in two pieces, in the usual ERFA
+- manner, which is designed to preserve time resolution. The
+- Julian Date is available as a single number by adding dj1 and
+- dj2. The maximum resolution is achieved if dj1 is 2451545.0
+- (J2000.0).
+-
+- Reference:
+-
+- Lieske, J.H., 1979. Astron.Astrophys., 73, 282.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.epb(dj1, dj2)
+- return c_retval
+-
+-
+-def epb2jd(epb):
+- """
+- Wrapper for ERFA function ``eraEpb2jd``.
+-
+- Parameters
+- ----------
+- epb : double array
+-
+- Returns
+- -------
+- djm0 : double array
+- djm : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E p b 2 j d
+- - - - - - - - - - -
+-
+- Besselian Epoch to Julian Date.
+-
+- Given:
+- epb double Besselian Epoch (e.g. 1957.3)
+-
+- Returned:
+- djm0 double MJD zero-point: always 2400000.5
+- djm double Modified Julian Date
+-
+- Note:
+-
+- The Julian Date is returned in two pieces, in the usual ERFA
+- manner, which is designed to preserve time resolution. The
+- Julian Date is available as a single number by adding djm0 and
+- djm.
+-
+- Reference:
+-
+- Lieske, J.H., 1979, Astron.Astrophys. 73, 282.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- djm0, djm = ufunc.epb2jd(epb)
+- return djm0, djm
+-
+-
+-def epj(dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraEpj``.
+-
+- Parameters
+- ----------
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a E p j
+- - - - - - - -
+-
+- Julian Date to Julian Epoch.
+-
+- Given:
+- dj1,dj2 double Julian Date (see note)
+-
+- Returned (function value):
+- double Julian Epoch
+-
+- Note:
+-
+- The Julian Date is supplied in two pieces, in the usual ERFA
+- manner, which is designed to preserve time resolution. The
+- Julian Date is available as a single number by adding dj1 and
+- dj2. The maximum resolution is achieved if dj1 is 2451545.0
+- (J2000.0).
+-
+- Reference:
+-
+- Lieske, J.H., 1979, Astron.Astrophys. 73, 282.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.epj(dj1, dj2)
+- return c_retval
+-
+-
+-def epj2jd(epj):
+- """
+- Wrapper for ERFA function ``eraEpj2jd``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- djm0 : double array
+- djm : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E p j 2 j d
+- - - - - - - - - - -
+-
+- Julian Epoch to Julian Date.
+-
+- Given:
+- epj double Julian Epoch (e.g. 1996.8)
+-
+- Returned:
+- djm0 double MJD zero-point: always 2400000.5
+- djm double Modified Julian Date
+-
+- Note:
+-
+- The Julian Date is returned in two pieces, in the usual ERFA
+- manner, which is designed to preserve time resolution. The
+- Julian Date is available as a single number by adding djm0 and
+- djm.
+-
+- Reference:
+-
+- Lieske, J.H., 1979, Astron.Astrophys. 73, 282.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- djm0, djm = ufunc.epj2jd(epj)
+- return djm0, djm
+-
+-
+-def jd2cal(dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraJd2cal``.
+-
+- Parameters
+- ----------
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- iy : int array
+- im : int array
+- id : int array
+- fd : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a J d 2 c a l
+- - - - - - - - - - -
+-
+- Julian Date to Gregorian year, month, day, and fraction of a day.
+-
+- Given:
+- dj1,dj2 double Julian Date (Notes 1, 2)
+-
+- Returned (arguments):
+- iy int year
+- im int month
+- id int day
+- fd double fraction of day
+-
+- Returned (function value):
+- int status:
+- 0 = OK
+- -1 = unacceptable date (Note 1)
+-
+- Notes:
+-
+- 1) The earliest valid date is -68569.5 (-4900 March 1). The
+- largest value accepted is 1e9.
+-
+- 2) The Julian Date is apportioned in any convenient way between
+- the arguments dj1 and dj2. For example, JD=2450123.7 could
+- be expressed in any of these ways, among others:
+-
+- dj1 dj2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- 3) In early eras the conversion is from the "proleptic Gregorian
+- calendar"; no account is taken of the date(s) of adoption of
+- the Gregorian calendar, nor is the AD/BC numbering convention
+- observed.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 12.92 (p604).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- iy, im, id, fd, c_retval = ufunc.jd2cal(dj1, dj2)
+- check_errwarn(c_retval, 'jd2cal')
+- return iy, im, id, fd
+-
+-
+-STATUS_CODES['jd2cal'] = {0: 'OK', -1: 'unacceptable date (Note 1)'}
+-
+-
+-def jdcalf(ndp, dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraJdcalf``.
+-
+- Parameters
+- ----------
+- ndp : int array
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- iymdf : int array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a J d c a l f
+- - - - - - - - - - -
+-
+- Julian Date to Gregorian Calendar, expressed in a form convenient
+- for formatting messages: rounded to a specified precision.
+-
+- Given:
+- ndp int number of decimal places of days in fraction
+- dj1,dj2 double dj1+dj2 = Julian Date (Note 1)
+-
+- Returned:
+- iymdf int[4] year, month, day, fraction in Gregorian
+- calendar
+-
+- Returned (function value):
+- int status:
+- -1 = date out of range
+- 0 = OK
+- +1 = NDP not 0-9 (interpreted as 0)
+-
+- Notes:
+-
+- 1) The Julian Date is apportioned in any convenient way between
+- the arguments dj1 and dj2. For example, JD=2450123.7 could
+- be expressed in any of these ways, among others:
+-
+- dj1 dj2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- 2) In early eras the conversion is from the "Proleptic Gregorian
+- Calendar"; no account is taken of the date(s) of adoption of
+- the Gregorian Calendar, nor is the AD/BC numbering convention
+- observed.
+-
+- 3) Refer to the function eraJd2cal.
+-
+- 4) NDP should be 4 or less if internal overflows are to be
+- avoided on machines which use 16-bit integers.
+-
+- Called:
+- eraJd2cal JD to Gregorian calendar
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 12.92 (p604).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- iymdf, c_retval = ufunc.jdcalf(ndp, dj1, dj2)
+- check_errwarn(c_retval, 'jdcalf')
+- return iymdf
+-
+-
+-STATUS_CODES['jdcalf'] = {-1: 'date out of range', 0: 'OK', 1: 'NDP not 0-9 (interpreted as 0)'}
+-
+-
+-def ab(pnat, v, s, bm1):
+- """
+- Wrapper for ERFA function ``eraAb``.
+-
+- Parameters
+- ----------
+- pnat : double array
+- v : double array
+- s : double array
+- bm1 : double array
+-
+- Returns
+- -------
+- ppr : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a A b
+- - - - - - -
+-
+- Apply aberration to transform natural direction into proper
+- direction.
+-
+- Given:
+- pnat double[3] natural direction to the source (unit vector)
+- v double[3] observer barycentric velocity in units of c
+- s double distance between the Sun and the observer (au)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+-
+- Returned:
+- ppr double[3] proper direction to source (unit vector)
+-
+- Notes:
+-
+- 1) The algorithm is based on Expr. (7.40) in the Explanatory
+- Supplement (Urban & Seidelmann 2013), but with the following
+- changes:
+-
+- o Rigorous rather than approximate normalization is applied.
+-
+- o The gravitational potential term from Expr. (7) in
+- Klioner (2003) is added, taking into account only the Sun's
+- contribution. This has a maximum effect of about
+- 0.4 microarcsecond.
+-
+- 2) In almost all cases, the maximum accuracy will be limited by the
+- supplied velocity. For example, if the ERFA eraEpv00 function is
+- used, errors of up to 5 microarcseconds could occur.
+-
+- References:
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013).
+-
+- Klioner, Sergei A., "A practical relativistic model for micro-
+- arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003).
+-
+- Called:
+- eraPdp scalar product of two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ppr = ufunc.ab(pnat, v, s, bm1)
+- return ppr
+-
+-
+-def apcg(date1, date2, ebpv, ehp):
+- """
+- Wrapper for ERFA function ``eraApcg``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- ebpv : double array
+- ehp : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A p c g
+- - - - - - - - -
+-
+- For a geocentric observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and GCRS coordinates.
+- The Earth ephemeris is supplied by the caller.
+-
+- The parameters produced by this function are required in the
+- parallax, light deflection and aberration parts of the astrometric
+- transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+- ebpv double[2][3] Earth barycentric pos/vel (au, au/day)
+- ehp double[3] Earth heliocentric position (au)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 4) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraApcs astrometry parameters, ICRS-GCRS, space observer
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apcg(date1, date2, ebpv, ehp)
+- return astrom
+-
+-
+-def apcg13(date1, date2):
+- """
+- Wrapper for ERFA function ``eraApcg13``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A p c g 1 3
+- - - - - - - - - - -
+-
+- For a geocentric observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and GCRS coordinates.
+- The caller supplies the date, and ERFA models are used to predict
+- the Earth ephemeris.
+-
+- The parameters produced by this function are required in the
+- parallax, light deflection and aberration parts of the astrometric
+- transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) In cases where the caller wishes to supply his own Earth
+- ephemeris, the function eraApcg can be used instead of the present
+- function.
+-
+- 4) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 5) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraEpv00 Earth position and velocity
+- eraApcg astrometry parameters, ICRS-GCRS, geocenter
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apcg13(date1, date2)
+- return astrom
+-
+-
+-def apci(date1, date2, ebpv, ehp, x, y, s):
+- """
+- Wrapper for ERFA function ``eraApci``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- ebpv : double array
+- ehp : double array
+- x : double array
+- y : double array
+- s : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A p c i
+- - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and geocentric CIRS
+- coordinates. The Earth ephemeris and CIP/CIO are supplied by the
+- caller.
+-
+- The parameters produced by this function are required in the
+- parallax, light deflection, aberration, and bias-precession-nutation
+- parts of the astrometric transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+- ebpv double[2][3] Earth barycentric position/velocity (au, au/day)
+- ehp double[3] Earth heliocentric position (au)
+- x,y double CIP X,Y (components of unit vector)
+- s double the CIO locator s (radians)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) In cases where the caller does not wish to provide the Earth
+- ephemeris and CIP/CIO, the function eraApci13 can be used instead
+- of the present function. This computes the required quantities
+- using other ERFA functions.
+-
+- 4) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 5) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraApcg astrometry parameters, ICRS-GCRS, geocenter
+- eraC2ixys celestial-to-intermediate matrix, given X,Y and s
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apci(date1, date2, ebpv, ehp, x, y, s)
+- return astrom
+-
+-
+-def apci13(date1, date2):
+- """
+- Wrapper for ERFA function ``eraApci13``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+- eo : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A p c i 1 3
+- - - - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and geocentric CIRS
+- coordinates. The caller supplies the date, and ERFA models are used
+- to predict the Earth ephemeris and CIP/CIO.
+-
+- The parameters produced by this function are required in the
+- parallax, light deflection, aberration, and bias-precession-nutation
+- parts of the astrometric transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+- eo double* equation of the origins (ERA-GST)
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) In cases where the caller wishes to supply his own Earth
+- ephemeris and CIP/CIO, the function eraApci can be used instead
+- of the present function.
+-
+- 4) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 5) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraEpv00 Earth position and velocity
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+- eraApci astrometry parameters, ICRS-CIRS
+- eraEors equation of the origins, given NPB matrix and s
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom, eo = ufunc.apci13(date1, date2)
+- return astrom, eo
+-
+-
+-def apco(date1, date2, ebpv, ehp, x, y, s, theta, elong, phi, hm, xp, yp, sp, refa, refb):
+- """
+- Wrapper for ERFA function ``eraApco``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- ebpv : double array
+- ehp : double array
+- x : double array
+- y : double array
+- s : double array
+- theta : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- sp : double array
+- refa : double array
+- refb : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A p c o
+- - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and observed
+- coordinates. The caller supplies the Earth ephemeris, the Earth
+- rotation information and the refraction constants as well as the
+- site coordinates.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+- ebpv double[2][3] Earth barycentric PV (au, au/day, Note 2)
+- ehp double[3] Earth heliocentric P (au, Note 2)
+- x,y double CIP X,Y (components of unit vector)
+- s double the CIO locator s (radians)
+- theta double Earth rotation angle (radians)
+- elong double longitude (radians, east +ve, Note 3)
+- phi double latitude (geodetic, radians, Note 3)
+- hm double height above ellipsoid (m, geodetic, Note 3)
+- xp,yp double polar motion coordinates (radians, Note 4)
+- sp double the TIO locator s' (radians, Note 4)
+- refa double refraction constant A (radians, Note 5)
+- refb double refraction constant B (radians, Note 5)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) The vectors eb, eh, and all the astrom vectors, are with respect
+- to BCRS axes.
+-
+- 3) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN
+- CONVENTION: the longitude required by the present function is
+- right-handed, i.e. east-positive, in accordance with geographical
+- convention.
+-
+- 4) xp and yp are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions), measured along the
+- meridians 0 and 90 deg west respectively. sp is the TIO locator
+- s', in radians, which positions the Terrestrial Intermediate
+- Origin on the equator. For many applications, xp, yp and
+- (especially) sp can be set to zero.
+-
+- Internally, the polar motion is stored in a form rotated onto the
+- local meridian.
+-
+- 5) The refraction constants refa and refb are for use in a
+- dZ = A*tan(Z)+B*tan^3(Z) model, where Z is the observed
+- (i.e. refracted) zenith distance and dZ is the amount of
+- refraction.
+-
+- 6) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- 7) In cases where the caller does not wish to provide the Earth
+- Ephemeris, the Earth rotation information and refraction
+- constants, the function eraApco13 can be used instead of the
+- present function. This starts from UTC and weather readings etc.
+- and computes suitable values using other ERFA functions.
+-
+- 8) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 9) The context structure astrom produced by this function is used by
+- eraAtioq, eraAtoiq, eraAtciq* and eraAticq*.
+-
+- Called:
+- eraAper astrometry parameters: update ERA
+- eraC2ixys celestial-to-intermediate matrix, given X,Y and s
+- eraPvtob position/velocity of terrestrial station
+- eraTrxpv product of transpose of r-matrix and pv-vector
+- eraApcs astrometry parameters, ICRS-GCRS, space observer
+- eraCr copy r-matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apco(date1, date2, ebpv, ehp, x, y, s, theta, elong, phi, hm, xp, yp, sp, refa, refb)
+- return astrom
+-
+-
+-def apco13(utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraApco13``.
+-
+- Parameters
+- ----------
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+- eo : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A p c o 1 3
+- - - - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between ICRS and observed
+- coordinates. The caller supplies UTC, site coordinates, ambient air
+- conditions and observing wavelength, and ERFA models are used to
+- obtain the Earth ephemeris, CIP/CIO and refraction constants.
+-
+- The parameters produced by this function are required in the
+- parallax, light deflection, aberration, and bias-precession-nutation
+- parts of the ICRS/CIRS transformations.
+-
+- Given:
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 1,2)
+- dut1 double UT1-UTC (seconds, Note 3)
+- elong double longitude (radians, east +ve, Note 4)
+- phi double latitude (geodetic, radians, Note 4)
+- hm double height above ellipsoid (m, geodetic, Notes 4,6)
+- xp,yp double polar motion coordinates (radians, Note 5)
+- phpa double pressure at the observer (hPa = mB, Note 6)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 7)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+- eo double* equation of the origins (ERA-GST)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 2)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 2) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the
+- future to be trusted. See eraDat for further details.
+-
+- 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 4) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 5) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many
+- applications, xp and yp can be set to zero.
+-
+- Internally, the polar motion is stored in a form rotated onto
+- the local meridian.
+-
+- 6) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB), is
+- available, an adequate estimate of hm can be obtained from the
+- expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to
+- the pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 7) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 8) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- 9) In cases where the caller wishes to supply his own Earth
+- ephemeris, Earth rotation information and refraction constants,
+- the function eraApco can be used instead of the present function.
+-
+- 10) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 11) The context structure astrom produced by this function is used
+- by eraAtioq, eraAtoiq, eraAtciq* and eraAticq*.
+-
+- Called:
+- eraUtctai UTC to TAI
+- eraTaitt TAI to TT
+- eraUtcut1 UTC to UT1
+- eraEpv00 Earth position and velocity
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+- eraEra00 Earth rotation angle, IAU 2000
+- eraSp00 the TIO locator s', IERS 2000
+- eraRefco refraction constants for given ambient conditions
+- eraApco astrometry parameters, ICRS-observed
+- eraEors equation of the origins, given NPB matrix and s
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom, eo, c_retval = ufunc.apco13(utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'apco13')
+- return astrom, eo
+-
+-
+-STATUS_CODES['apco13'] = {1: 'dubious year (Note 2)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def apcs(date1, date2, pv, ebpv, ehp):
+- """
+- Wrapper for ERFA function ``eraApcs``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- pv : double array
+- ebpv : double array
+- ehp : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A p c s
+- - - - - - - - -
+-
+- For an observer whose geocentric position and velocity are known,
+- prepare star-independent astrometry parameters for transformations
+- between ICRS and GCRS. The Earth ephemeris is supplied by the
+- caller.
+-
+- The parameters produced by this function are required in the space
+- motion, parallax, light deflection and aberration parts of the
+- astrometric transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+- pv double[2][3] observer's geocentric pos/vel (m, m/s)
+- ebpv double[2][3] Earth barycentric PV (au, au/day)
+- ehp double[3] Earth heliocentric P (au)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) Providing separate arguments for (i) the observer's geocentric
+- position and velocity and (ii) the Earth ephemeris is done for
+- convenience in the geocentric, terrestrial and Earth orbit cases.
+- For deep space applications it maybe more convenient to specify
+- zero geocentric position and velocity and to supply the
+- observer's position and velocity information directly instead of
+- with respect to the Earth. However, note the different units:
+- m and m/s for the geocentric vectors, au and au/day for the
+- heliocentric and barycentric vectors.
+-
+- 4) In cases where the caller does not wish to provide the Earth
+- ephemeris, the function eraApcs13 can be used instead of the
+- present function. This computes the Earth ephemeris using the
+- ERFA function eraEpv00.
+-
+- 5) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 6) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraCp copy p-vector
+- eraPm modulus of p-vector
+- eraPn decompose p-vector into modulus and direction
+- eraIr initialize r-matrix to identity
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apcs(date1, date2, pv, ebpv, ehp)
+- return astrom
+-
+-
+-def apcs13(date1, date2, pv):
+- """
+- Wrapper for ERFA function ``eraApcs13``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- pv : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A p c s 1 3
+- - - - - - - - - - -
+-
+- For an observer whose geocentric position and velocity are known,
+- prepare star-independent astrometry parameters for transformations
+- between ICRS and GCRS. The Earth ephemeris is from ERFA models.
+-
+- The parameters produced by this function are required in the space
+- motion, parallax, light deflection and aberration parts of the
+- astrometric transformation chain.
+-
+- Given:
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+- pv double[2][3] observer's geocentric pos/vel (Note 3)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double unchanged
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) All the vectors are with respect to BCRS axes.
+-
+- 3) The observer's position and velocity pv are geocentric but with
+- respect to BCRS axes, and in units of m and m/s. No assumptions
+- are made about proximity to the Earth, and the function can be
+- used for deep space applications as well as Earth orbit and
+- terrestrial.
+-
+- 4) In cases where the caller wishes to supply his own Earth
+- ephemeris, the function eraApcs can be used instead of the present
+- function.
+-
+- 5) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 6) The context structure astrom produced by this function is used by
+- eraAtciq* and eraAticq*.
+-
+- Called:
+- eraEpv00 Earth position and velocity
+- eraApcs astrometry parameters, ICRS-GCRS, space observer
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apcs13(date1, date2, pv)
+- return astrom
+-
+-
+-def aper(theta, astrom):
+- """
+- Wrapper for ERFA function ``eraAper``.
+-
+- Parameters
+- ----------
+- theta : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below. Note that, unlike the erfa routine,
+- the python wrapper does not change astrom in-place.
+-
+- - - - - - - - -
+- e r a A p e r
+- - - - - - - - -
+-
+- In the star-independent astrometry parameters, update only the
+- Earth rotation angle, supplied by the caller explicitly.
+-
+- Given:
+- theta double Earth rotation angle (radians, Note 2)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double not used
+- eb double[3] not used
+- eh double[3] not used
+- em double not used
+- v double[3] not used
+- bm1 double not used
+- bpn double[3][3] not used
+- along double longitude + s' (radians)
+- xpl double not used
+- ypl double not used
+- sphi double not used
+- cphi double not used
+- diurab double not used
+- eral double not used
+- refa double not used
+- refb double not used
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double unchanged
+- eb double[3] unchanged
+- eh double[3] unchanged
+- em double unchanged
+- v double[3] unchanged
+- bm1 double unchanged
+- bpn double[3][3] unchanged
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double "local" Earth rotation angle (radians)
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) This function exists to enable sidereal-tracking applications to
+- avoid wasteful recomputation of the bulk of the astrometry
+- parameters: only the Earth rotation is updated.
+-
+- 2) For targets expressed as equinox based positions, such as
+- classical geocentric apparent (RA,Dec), the supplied theta can be
+- Greenwich apparent sidereal time rather than Earth rotation
+- angle.
+-
+- 3) The function eraAper13 can be used instead of the present
+- function, and starts from UT1 rather than ERA itself.
+-
+- 4) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.aper(theta, astrom)
+- return astrom
+-
+-
+-def aper13(ut11, ut12, astrom):
+- """
+- Wrapper for ERFA function ``eraAper13``.
+-
+- Parameters
+- ----------
+- ut11 : double array
+- ut12 : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below. Note that, unlike the erfa routine,
+- the python wrapper does not change astrom in-place.
+-
+- - - - - - - - - - -
+- e r a A p e r 1 3
+- - - - - - - - - - -
+-
+- In the star-independent astrometry parameters, update only the
+- Earth rotation angle. The caller provides UT1, (n.b. not UTC).
+-
+- Given:
+- ut11 double UT1 as a 2-part...
+- ut12 double ...Julian Date (Note 1)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double not used
+- eb double[3] not used
+- eh double[3] not used
+- em double not used
+- v double[3] not used
+- bm1 double not used
+- bpn double[3][3] not used
+- along double longitude + s' (radians)
+- xpl double not used
+- ypl double not used
+- sphi double not used
+- cphi double not used
+- diurab double not used
+- eral double not used
+- refa double not used
+- refb double not used
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double unchanged
+- eb double[3] unchanged
+- eh double[3] unchanged
+- em double unchanged
+- v double[3] unchanged
+- bm1 double unchanged
+- bpn double[3][3] unchanged
+- along double unchanged
+- xpl double unchanged
+- ypl double unchanged
+- sphi double unchanged
+- cphi double unchanged
+- diurab double unchanged
+- eral double "local" Earth rotation angle (radians)
+- refa double unchanged
+- refb double unchanged
+-
+- Notes:
+-
+- 1) The UT1 date (n.b. not UTC) ut11+ut12 is a Julian Date,
+- apportioned in any convenient way between the arguments ut11 and
+- ut12. For example, JD(UT1)=2450123.7 could be expressed in any
+- of these ways, among others:
+-
+- ut11 ut12
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. The date & time method is
+- best matched to the algorithm used: maximum precision is
+- delivered when the ut11 argument is for 0hrs UT1 on the day in
+- question and the ut12 argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) If the caller wishes to provide the Earth rotation angle itself,
+- the function eraAper can be used instead. One use of this
+- technique is to substitute Greenwich apparent sidereal time and
+- thereby to support equinox based transformations directly.
+-
+- 3) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- Called:
+- eraAper astrometry parameters: update ERA
+- eraEra00 Earth rotation angle, IAU 2000
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.aper13(ut11, ut12, astrom)
+- return astrom
+-
+-
+-def apio(sp, theta, elong, phi, hm, xp, yp, refa, refb):
+- """
+- Wrapper for ERFA function ``eraApio``.
+-
+- Parameters
+- ----------
+- sp : double array
+- theta : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- refa : double array
+- refb : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A p i o
+- - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between CIRS and observed
+- coordinates. The caller supplies the Earth orientation information
+- and the refraction constants as well as the site coordinates.
+-
+- Given:
+- sp double the TIO locator s' (radians, Note 1)
+- theta double Earth rotation angle (radians)
+- elong double longitude (radians, east +ve, Note 2)
+- phi double geodetic latitude (radians, Note 2)
+- hm double height above ellipsoid (m, geodetic Note 2)
+- xp,yp double polar motion coordinates (radians, Note 3)
+- refa double refraction constant A (radians, Note 4)
+- refb double refraction constant B (radians, Note 4)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double unchanged
+- eb double[3] unchanged
+- eh double[3] unchanged
+- em double unchanged
+- v double[3] unchanged
+- bm1 double unchanged
+- bpn double[3][3] unchanged
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Notes:
+-
+- 1) sp, the TIO locator s', is a tiny quantity needed only by the
+- most precise applications. It can either be set to zero or
+- predicted using the ERFA function eraSp00.
+-
+- 2) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 3) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many applications,
+- xp and yp can be set to zero.
+-
+- Internally, the polar motion is stored in a form rotated onto the
+- local meridian.
+-
+- 4) The refraction constants refa and refb are for use in a
+- dZ = A*tan(Z)+B*tan^3(Z) model, where Z is the observed
+- (i.e. refracted) zenith distance and dZ is the amount of
+- refraction.
+-
+- 5) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- 6) In cases where the caller does not wish to provide the Earth
+- rotation information and refraction constants, the function
+- eraApio13 can be used instead of the present function. This
+- starts from UTC and weather readings etc. and computes suitable
+- values using other ERFA functions.
+-
+- 7) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 8) The context structure astrom produced by this function is used by
+- eraAtioq and eraAtoiq.
+-
+- Called:
+- eraPvtob position/velocity of terrestrial station
+- eraAper astrometry parameters: update ERA
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom = ufunc.apio(sp, theta, elong, phi, hm, xp, yp, refa, refb)
+- return astrom
+-
+-
+-def apio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraApio13``.
+-
+- Parameters
+- ----------
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- astrom : eraASTROM array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A p i o 1 3
+- - - - - - - - - - -
+-
+- For a terrestrial observer, prepare star-independent astrometry
+- parameters for transformations between CIRS and observed
+- coordinates. The caller supplies UTC, site coordinates, ambient air
+- conditions and observing wavelength.
+-
+- Given:
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 1,2)
+- dut1 double UT1-UTC (seconds)
+- elong double longitude (radians, east +ve, Note 3)
+- phi double geodetic latitude (radians, Note 3)
+- hm double height above ellipsoid (m, geodetic Notes 4,6)
+- xp,yp double polar motion coordinates (radians, Note 5)
+- phpa double pressure at the observer (hPa = mB, Note 6)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 7)
+-
+- Returned:
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double unchanged
+- eb double[3] unchanged
+- eh double[3] unchanged
+- em double unchanged
+- v double[3] unchanged
+- bm1 double unchanged
+- bpn double[3][3] unchanged
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 2)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 2) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 4) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 5) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many applications,
+- xp and yp can be set to zero.
+-
+- Internally, the polar motion is stored in a form rotated onto
+- the local meridian.
+-
+- 6) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB), is
+- available, an adequate estimate of hm can be obtained from the
+- expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to the
+- pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 7) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 8) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- 9) In cases where the caller wishes to supply his own Earth
+- rotation information and refraction constants, the function
+- eraApc can be used instead of the present function.
+-
+- 10) This is one of several functions that inserts into the astrom
+- structure star-independent parameters needed for the chain of
+- astrometric transformations ICRS <-> GCRS <-> CIRS <-> observed.
+-
+- The various functions support different classes of observer and
+- portions of the transformation chain:
+-
+- functions observer transformation
+-
+- eraApcg eraApcg13 geocentric ICRS <-> GCRS
+- eraApci eraApci13 terrestrial ICRS <-> CIRS
+- eraApco eraApco13 terrestrial ICRS <-> observed
+- eraApcs eraApcs13 space ICRS <-> GCRS
+- eraAper eraAper13 terrestrial update Earth rotation
+- eraApio eraApio13 terrestrial CIRS <-> observed
+-
+- Those with names ending in "13" use contemporary ERFA models to
+- compute the various ephemerides. The others accept ephemerides
+- supplied by the caller.
+-
+- The transformation from ICRS to GCRS covers space motion,
+- parallax, light deflection, and aberration. From GCRS to CIRS
+- comprises frame bias and precession-nutation. From CIRS to
+- observed takes account of Earth rotation, polar motion, diurnal
+- aberration and parallax (unless subsumed into the ICRS <-> GCRS
+- transformation), and atmospheric refraction.
+-
+- 11) The context structure astrom produced by this function is used
+- by eraAtioq and eraAtoiq.
+-
+- Called:
+- eraUtctai UTC to TAI
+- eraTaitt TAI to TT
+- eraUtcut1 UTC to UT1
+- eraSp00 the TIO locator s', IERS 2000
+- eraEra00 Earth rotation angle, IAU 2000
+- eraRefco refraction constants for given ambient conditions
+- eraApio astrometry parameters, CIRS-observed
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- astrom, c_retval = ufunc.apio13(utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'apio13')
+- return astrom
+-
+-
+-STATUS_CODES['apio13'] = {1: 'dubious year (Note 2)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def atci13(rc, dc, pr, pd, px, rv, date1, date2):
+- """
+- Wrapper for ERFA function ``eraAtci13``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- pr : double array
+- pd : double array
+- px : double array
+- rv : double array
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+- eo : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t c i 1 3
+- - - - - - - - - - -
+-
+- Transform ICRS star data, epoch J2000.0, to CIRS.
+-
+- Given:
+- rc double ICRS right ascension at J2000.0 (radians, Note 1)
+- dc double ICRS declination at J2000.0 (radians, Note 1)
+- pr double RA proper motion (radians/year; Note 2)
+- pd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, +ve if receding)
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 3)
+-
+- Returned:
+- ri,di double* CIRS geocentric RA,Dec (radians)
+- eo double* equation of the origins (ERA-GST, Note 5)
+-
+- Notes:
+-
+- 1) Star data for an epoch other than J2000.0 (for example from the
+- Hipparcos catalog, which has an epoch of J1991.25) will require a
+- preliminary call to eraPmsafe before use.
+-
+- 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- 3) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 4) The available accuracy is better than 1 milliarcsecond, limited
+- mainly by the precession-nutation model that is used, namely
+- IAU 2000A/2006. Very close to solar system bodies, additional
+- errors of up to several milliarcseconds can occur because of
+- unmodeled light deflection; however, the Sun's contribution is
+- taken into account, to first order. The accuracy limitations of
+- the ERFA function eraEpv00 (used to compute Earth position and
+- velocity) can contribute aberration errors of up to
+- 5 microarcseconds. Light deflection at the Sun's limb is
+- uncertain at the 0.4 mas level.
+-
+- 5) Should the transformation to (equinox based) apparent place be
+- required rather than (CIO based) intermediate place, subtract the
+- equation of the origins from the returned right ascension:
+- RA = RI - EO. (The eraAnp function can then be applied, as
+- required, to keep the result in the conventional 0-2pi range.)
+-
+- Called:
+- eraApci13 astrometry parameters, ICRS-CIRS, 2013
+- eraAtciq quick ICRS to CIRS
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di, eo = ufunc.atci13(rc, dc, pr, pd, px, rv, date1, date2)
+- return ri, di, eo
+-
+-
+-def atciq(rc, dc, pr, pd, px, rv, astrom):
+- """
+- Wrapper for ERFA function ``eraAtciq``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- pr : double array
+- pd : double array
+- px : double array
+- rv : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a A t c i q
+- - - - - - - - - -
+-
+- Quick ICRS, epoch J2000.0, to CIRS transformation, given precomputed
+- star-independent astrometry parameters.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are to be transformed for one date. The
+- star-independent parameters can be obtained by calling one of the
+- functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13].
+-
+- If the parallax and proper motions are zero the eraAtciqz function
+- can be used instead.
+-
+- Given:
+- rc,dc double ICRS RA,Dec at J2000.0 (radians)
+- pr double RA proper motion (radians/year; Note 3)
+- pd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, +ve if receding)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned:
+- ri,di double CIRS RA,Dec (radians)
+-
+- Notes:
+-
+- 1) All the vectors are with respect to BCRS axes.
+-
+- 2) Star data for an epoch other than J2000.0 (for example from the
+- Hipparcos catalog, which has an epoch of J1991.25) will require a
+- preliminary call to eraPmsafe before use.
+-
+- 3) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- Called:
+- eraPmpx proper motion and parallax
+- eraLdsun light deflection by the Sun
+- eraAb stellar aberration
+- eraRxp product of r-matrix and pv-vector
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di = ufunc.atciq(rc, dc, pr, pd, px, rv, astrom)
+- return ri, di
+-
+-
+-def atciqn(rc, dc, pr, pd, px, rv, astrom, b):
+- """
+- Wrapper for ERFA function ``eraAtciqn``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- pr : double array
+- pd : double array
+- px : double array
+- rv : double array
+- astrom : eraASTROM array
+- b : eraLDBODY array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t c i q n
+- - - - - - - - - - -
+-
+- Quick ICRS, epoch J2000.0, to CIRS transformation, given precomputed
+- star-independent astrometry parameters plus a list of light-
+- deflecting bodies.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are to be transformed for one date. The
+- star-independent parameters can be obtained by calling one of the
+- functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13].
+-
+-
+- If the only light-deflecting body to be taken into account is the
+- Sun, the eraAtciq function can be used instead. If in addition the
+- parallax and proper motions are zero, the eraAtciqz function can be
+- used.
+-
+- Given:
+- rc,dc double ICRS RA,Dec at J2000.0 (radians)
+- pr double RA proper motion (radians/year; Note 3)
+- pd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, +ve if receding)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+- n int number of bodies (Note 3)
+- b eraLDBODY[n] data for each of the n bodies (Notes 3,4):
+- bm double mass of the body (solar masses, Note 5)
+- dl double deflection limiter (Note 6)
+- pv [2][3] barycentric PV of the body (au, au/day)
+-
+- Returned:
+- ri,di double CIRS RA,Dec (radians)
+-
+- Notes:
+-
+- 1) Star data for an epoch other than J2000.0 (for example from the
+- Hipparcos catalog, which has an epoch of J1991.25) will require a
+- preliminary call to eraPmsafe before use.
+-
+- 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- 3) The struct b contains n entries, one for each body to be
+- considered. If n = 0, no gravitational light deflection will be
+- applied, not even for the Sun.
+-
+- 4) The struct b should include an entry for the Sun as well as for
+- any planet or other body to be taken into account. The entries
+- should be in the order in which the light passes the body.
+-
+- 5) In the entry in the b struct for body i, the mass parameter
+- b[i].bm can, as required, be adjusted in order to allow for such
+- effects as quadrupole field.
+-
+- 6) The deflection limiter parameter b[i].dl is phi^2/2, where phi is
+- the angular separation (in radians) between star and body at
+- which limiting is applied. As phi shrinks below the chosen
+- threshold, the deflection is artificially reduced, reaching zero
+- for phi = 0. Example values suitable for a terrestrial
+- observer, together with masses, are as follows:
+-
+- body i b[i].bm b[i].dl
+-
+- Sun 1.0 6e-6
+- Jupiter 0.00095435 3e-9
+- Saturn 0.00028574 3e-10
+-
+- 7) For efficiency, validation of the contents of the b array is
+- omitted. The supplied masses must be greater than zero, the
+- position and velocity vectors must be right, and the deflection
+- limiter greater than zero.
+-
+- Called:
+- eraPmpx proper motion and parallax
+- eraLdn light deflection by n bodies
+- eraAb stellar aberration
+- eraRxp product of r-matrix and pv-vector
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di = ufunc.atciqn(rc, dc, pr, pd, px, rv, astrom, b)
+- return ri, di
+-
+-
+-def atciqz(rc, dc, astrom):
+- """
+- Wrapper for ERFA function ``eraAtciqz``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t c i q z
+- - - - - - - - - - -
+-
+- Quick ICRS to CIRS transformation, given precomputed star-
+- independent astrometry parameters, and assuming zero parallax and
+- proper motion.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are to be transformed for one date. The
+- star-independent parameters can be obtained by calling one of the
+- functions eraApci[13], eraApcg[13], eraApco[13] or eraApcs[13].
+-
+- The corresponding function for the case of non-zero parallax and
+- proper motion is eraAtciq.
+-
+- Given:
+- rc,dc double ICRS astrometric RA,Dec (radians)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned:
+- ri,di double CIRS RA,Dec (radians)
+-
+- Note:
+-
+- All the vectors are with respect to BCRS axes.
+-
+- References:
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013).
+-
+- Klioner, Sergei A., "A practical relativistic model for micro-
+- arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003).
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraLdsun light deflection due to Sun
+- eraAb stellar aberration
+- eraRxp product of r-matrix and p-vector
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range +/- pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di = ufunc.atciqz(rc, dc, astrom)
+- return ri, di
+-
+-
+-def atco13(rc, dc, pr, pd, px, rv, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraAtco13``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- pr : double array
+- pd : double array
+- px : double array
+- rv : double array
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- aob : double array
+- zob : double array
+- hob : double array
+- dob : double array
+- rob : double array
+- eo : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t c o 1 3
+- - - - - - - - - - -
+-
+- ICRS RA,Dec to observed place. The caller supplies UTC, site
+- coordinates, ambient air conditions and observing wavelength.
+-
+- ERFA models are used for the Earth ephemeris, bias-precession-
+- nutation, Earth orientation and refraction.
+-
+- Given:
+- rc,dc double ICRS right ascension at J2000.0 (radians, Note 1)
+- pr double RA proper motion (radians/year; Note 2)
+- pd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, +ve if receding)
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 3-4)
+- dut1 double UT1-UTC (seconds, Note 5)
+- elong double longitude (radians, east +ve, Note 6)
+- phi double latitude (geodetic, radians, Note 6)
+- hm double height above ellipsoid (m, geodetic, Notes 6,8)
+- xp,yp double polar motion coordinates (radians, Note 7)
+- phpa double pressure at the observer (hPa = mB, Note 8)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 9)
+-
+- Returned:
+- aob double* observed azimuth (radians: N=0,E=90)
+- zob double* observed zenith distance (radians)
+- hob double* observed hour angle (radians)
+- dob double* observed declination (radians)
+- rob double* observed right ascension (CIO-based, radians)
+- eo double* equation of the origins (ERA-GST)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 4)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) Star data for an epoch other than J2000.0 (for example from the
+- Hipparcos catalog, which has an epoch of J1991.25) will require
+- a preliminary call to eraPmsafe before use.
+-
+- 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 4) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the
+- future to be trusted. See eraDat for further details.
+-
+- 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 6) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 7) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many
+- applications, xp and yp can be set to zero.
+-
+- 8) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB),
+- is available, an adequate estimate of hm can be obtained from
+- the expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to
+- the pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 9) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 10) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted observed
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better
+- than 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- Without refraction, the complementary functions eraAtco13 and
+- eraAtoc13 are self-consistent to better than 1 microarcsecond
+- all over the celestial sphere. With refraction included,
+- consistency falls off at high zenith distances, but is still
+- better than 0.05 arcsec at 85 degrees.
+-
+- 11) "Observed" Az,ZD means the position that would be seen by a
+- perfect geodetically aligned theodolite. (Zenith distance is
+- used rather than altitude in order to reflect the fact that no
+- allowance is made for depression of the horizon.) This is
+- related to the observed HA,Dec via the standard rotation, using
+- the geodetic latitude (corrected for polar motion), while the
+- observed HA and RA are related simply through the Earth rotation
+- angle and the site longitude. "Observed" RA,Dec or HA,Dec thus
+- means the position that would be seen by a perfect equatorial
+- with its polar axis aligned to the Earth's axis of rotation.
+-
+- 12) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- Called:
+- eraApco13 astrometry parameters, ICRS-observed, 2013
+- eraAtciq quick ICRS to CIRS
+- eraAtioq quick CIRS to observed
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- aob, zob, hob, dob, rob, eo, c_retval = ufunc.atco13(rc, dc, pr, pd, px, rv, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'atco13')
+- return aob, zob, hob, dob, rob, eo
+-
+-
+-STATUS_CODES['atco13'] = {1: 'dubious year (Note 4)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def atic13(ri, di, date1, date2):
+- """
+- Wrapper for ERFA function ``eraAtic13``.
+-
+- Parameters
+- ----------
+- ri : double array
+- di : double array
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rc : double array
+- dc : double array
+- eo : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t i c 1 3
+- - - - - - - - - - -
+-
+- Transform star RA,Dec from geocentric CIRS to ICRS astrometric.
+-
+- Given:
+- ri,di double CIRS geocentric RA,Dec (radians)
+- date1 double TDB as a 2-part...
+- date2 double ...Julian Date (Note 1)
+-
+- Returned:
+- rc,dc double ICRS astrometric RA,Dec (radians)
+- eo double equation of the origins (ERA-GST, Note 4)
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. For most
+- applications of this function the choice will not be at all
+- critical.
+-
+- TT can be used instead of TDB without any significant impact on
+- accuracy.
+-
+- 2) Iterative techniques are used for the aberration and light
+- deflection corrections so that the functions eraAtic13 (or
+- eraAticq) and eraAtci13 (or eraAtciq) are accurate inverses;
+- even at the edge of the Sun's disk the discrepancy is only about
+- 1 nanoarcsecond.
+-
+- 3) The available accuracy is better than 1 milliarcsecond, limited
+- mainly by the precession-nutation model that is used, namely
+- IAU 2000A/2006. Very close to solar system bodies, additional
+- errors of up to several milliarcseconds can occur because of
+- unmodeled light deflection; however, the Sun's contribution is
+- taken into account, to first order. The accuracy limitations of
+- the ERFA function eraEpv00 (used to compute Earth position and
+- velocity) can contribute aberration errors of up to
+- 5 microarcseconds. Light deflection at the Sun's limb is
+- uncertain at the 0.4 mas level.
+-
+- 4) Should the transformation to (equinox based) J2000.0 mean place
+- be required rather than (CIO based) ICRS coordinates, subtract the
+- equation of the origins from the returned right ascension:
+- RA = RI - EO. (The eraAnp function can then be applied, as
+- required, to keep the result in the conventional 0-2pi range.)
+-
+- Called:
+- eraApci13 astrometry parameters, ICRS-CIRS, 2013
+- eraAticq quick CIRS to ICRS astrometric
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc, dc, eo = ufunc.atic13(ri, di, date1, date2)
+- return rc, dc, eo
+-
+-
+-def aticq(ri, di, astrom):
+- """
+- Wrapper for ERFA function ``eraAticq``.
+-
+- Parameters
+- ----------
+- ri : double array
+- di : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- rc : double array
+- dc : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a A t i c q
+- - - - - - - - - -
+-
+- Quick CIRS RA,Dec to ICRS astrometric place, given the star-
+- independent astrometry parameters.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are all to be transformed for one date.
+- The star-independent astrometry parameters can be obtained by
+- calling one of the functions eraApci[13], eraApcg[13], eraApco[13]
+- or eraApcs[13].
+-
+- Given:
+- ri,di double CIRS RA,Dec (radians)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned:
+- rc,dc double ICRS astrometric RA,Dec (radians)
+-
+- Notes:
+-
+- 1) Only the Sun is taken into account in the light deflection
+- correction.
+-
+- 2) Iterative techniques are used for the aberration and light
+- deflection corrections so that the functions eraAtic13 (or
+- eraAticq) and eraAtci13 (or eraAtciq) are accurate inverses;
+- even at the edge of the Sun's disk the discrepancy is only about
+- 1 nanoarcsecond.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraZp zero p-vector
+- eraAb stellar aberration
+- eraLdsun light deflection by the Sun
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range +/- pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc, dc = ufunc.aticq(ri, di, astrom)
+- return rc, dc
+-
+-
+-def aticqn(ri, di, astrom, b):
+- """
+- Wrapper for ERFA function ``eraAticqn``.
+-
+- Parameters
+- ----------
+- ri : double array
+- di : double array
+- astrom : eraASTROM array
+- b : eraLDBODY array
+-
+- Returns
+- -------
+- rc : double array
+- dc : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t i c q n
+- - - - - - - - - - -
+-
+- Quick CIRS to ICRS astrometric place transformation, given the star-
+- independent astrometry parameters plus a list of light-deflecting
+- bodies.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are all to be transformed for one date.
+- The star-independent astrometry parameters can be obtained by
+- calling one of the functions eraApci[13], eraApcg[13], eraApco[13]
+- or eraApcs[13].
+-*
+-* If the only light-deflecting body to be taken into account is the
+-* Sun, the eraAticq function can be used instead.
+-
+- Given:
+- ri,di double CIRS RA,Dec (radians)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+- n int number of bodies (Note 3)
+- b eraLDBODY[n] data for each of the n bodies (Notes 3,4):
+- bm double mass of the body (solar masses, Note 5)
+- dl double deflection limiter (Note 6)
+- pv [2][3] barycentric PV of the body (au, au/day)
+-
+- Returned:
+- rc,dc double ICRS astrometric RA,Dec (radians)
+-
+- Notes:
+-
+- 1) Iterative techniques are used for the aberration and light
+- deflection corrections so that the functions eraAticqn and
+- eraAtciqn are accurate inverses; even at the edge of the Sun's
+- disk the discrepancy is only about 1 nanoarcsecond.
+-
+- 2) If the only light-deflecting body to be taken into account is the
+- Sun, the eraAticq function can be used instead.
+-
+- 3) The struct b contains n entries, one for each body to be
+- considered. If n = 0, no gravitational light deflection will be
+- applied, not even for the Sun.
+-
+- 4) The struct b should include an entry for the Sun as well as for
+- any planet or other body to be taken into account. The entries
+- should be in the order in which the light passes the body.
+-
+- 5) In the entry in the b struct for body i, the mass parameter
+- b[i].bm can, as required, be adjusted in order to allow for such
+- effects as quadrupole field.
+-
+- 6) The deflection limiter parameter b[i].dl is phi^2/2, where phi is
+- the angular separation (in radians) between star and body at
+- which limiting is applied. As phi shrinks below the chosen
+- threshold, the deflection is artificially reduced, reaching zero
+- for phi = 0. Example values suitable for a terrestrial
+- observer, together with masses, are as follows:
+-
+- body i b[i].bm b[i].dl
+-
+- Sun 1.0 6e-6
+- Jupiter 0.00095435 3e-9
+- Saturn 0.00028574 3e-10
+-
+- 7) For efficiency, validation of the contents of the b array is
+- omitted. The supplied masses must be greater than zero, the
+- position and velocity vectors must be right, and the deflection
+- limiter greater than zero.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraZp zero p-vector
+- eraAb stellar aberration
+- eraLdn light deflection by n bodies
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range +/- pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc, dc = ufunc.aticqn(ri, di, astrom, b)
+- return rc, dc
+-
+-
+-def atio13(ri, di, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraAtio13``.
+-
+- Parameters
+- ----------
+- ri : double array
+- di : double array
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- aob : double array
+- zob : double array
+- hob : double array
+- dob : double array
+- rob : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t i o 1 3
+- - - - - - - - - - -
+-
+- CIRS RA,Dec to observed place. The caller supplies UTC, site
+- coordinates, ambient air conditions and observing wavelength.
+-
+- Given:
+- ri double CIRS right ascension (CIO-based, radians)
+- di double CIRS declination (radians)
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 1,2)
+- dut1 double UT1-UTC (seconds, Note 3)
+- elong double longitude (radians, east +ve, Note 4)
+- phi double geodetic latitude (radians, Note 4)
+- hm double height above ellipsoid (m, geodetic Notes 4,6)
+- xp,yp double polar motion coordinates (radians, Note 5)
+- phpa double pressure at the observer (hPa = mB, Note 6)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 7)
+-
+- Returned:
+- aob double* observed azimuth (radians: N=0,E=90)
+- zob double* observed zenith distance (radians)
+- hob double* observed hour angle (radians)
+- dob double* observed declination (radians)
+- rob double* observed right ascension (CIO-based, radians)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 2)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 2) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the
+- future to be trusted. See eraDat for further details.
+-
+- 3) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 4) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 5) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many
+- applications, xp and yp can be set to zero.
+-
+- 6) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB), is
+- available, an adequate estimate of hm can be obtained from the
+- expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to
+- the pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 7) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 8) "Observed" Az,ZD means the position that would be seen by a
+- perfect geodetically aligned theodolite. (Zenith distance is
+- used rather than altitude in order to reflect the fact that no
+- allowance is made for depression of the horizon.) This is
+- related to the observed HA,Dec via the standard rotation, using
+- the geodetic latitude (corrected for polar motion), while the
+- observed HA and RA are related simply through the Earth rotation
+- angle and the site longitude. "Observed" RA,Dec or HA,Dec thus
+- means the position that would be seen by a perfect equatorial
+- with its polar axis aligned to the Earth's axis of rotation.
+-
+- 9) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted astrometric
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better
+- than 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- 10) The complementary functions eraAtio13 and eraAtoi13 are self-
+- consistent to better than 1 microarcsecond all over the
+- celestial sphere.
+-
+- 11) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- Called:
+- eraApio13 astrometry parameters, CIRS-observed, 2013
+- eraAtioq quick CIRS to observed
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- aob, zob, hob, dob, rob, c_retval = ufunc.atio13(ri, di, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'atio13')
+- return aob, zob, hob, dob, rob
+-
+-
+-STATUS_CODES['atio13'] = {1: 'dubious year (Note 2)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def atioq(ri, di, astrom):
+- """
+- Wrapper for ERFA function ``eraAtioq``.
+-
+- Parameters
+- ----------
+- ri : double array
+- di : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- aob : double array
+- zob : double array
+- hob : double array
+- dob : double array
+- rob : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a A t i o q
+- - - - - - - - - -
+-
+- Quick CIRS to observed place transformation.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are all to be transformed for one date.
+- The star-independent astrometry parameters can be obtained by
+- calling eraApio[13] or eraApco[13].
+-
+- Given:
+- ri double CIRS right ascension
+- di double CIRS declination
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned:
+- aob double* observed azimuth (radians: N=0,E=90)
+- zob double* observed zenith distance (radians)
+- hob double* observed hour angle (radians)
+- dob double* observed declination (radians)
+- rob double* observed right ascension (CIO-based, radians)
+-
+- Notes:
+-
+- 1) This function returns zenith distance rather than altitude in
+- order to reflect the fact that no allowance is made for
+- depression of the horizon.
+-
+- 2) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted observed
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better
+- than 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- Without refraction, the complementary functions eraAtioq and
+- eraAtoiq are self-consistent to better than 1 microarcsecond all
+- over the celestial sphere. With refraction included, consistency
+- falls off at high zenith distances, but is still better than
+- 0.05 arcsec at 85 degrees.
+-
+- 3) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- 4) The CIRS RA,Dec is obtained from a star catalog mean place by
+- allowing for space motion, parallax, the Sun's gravitational lens
+- effect, annual aberration and precession-nutation. For star
+- positions in the ICRS, these effects can be applied by means of
+- the eraAtci13 (etc.) functions. Starting from classical "mean
+- place" systems, additional transformations will be needed first.
+-
+- 5) "Observed" Az,El means the position that would be seen by a
+- perfect geodetically aligned theodolite. This is obtained from
+- the CIRS RA,Dec by allowing for Earth orientation and diurnal
+- aberration, rotating from equator to horizon coordinates, and
+- then adjusting for refraction. The HA,Dec is obtained by
+- rotating back into equatorial coordinates, and is the position
+- that would be seen by a perfect equatorial with its polar axis
+- aligned to the Earth's axis of rotation. Finally, the RA is
+- obtained by subtracting the HA from the local ERA.
+-
+- 6) The star-independent CIRS-to-observed-place parameters in ASTROM
+- may be computed with eraApio[13] or eraApco[13]. If nothing has
+- changed significantly except the time, eraAper[13] may be used to
+- perform the requisite adjustment to the astrom structure.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- aob, zob, hob, dob, rob = ufunc.atioq(ri, di, astrom)
+- return aob, zob, hob, dob, rob
+-
+-
+-def atoc13(type, ob1, ob2, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraAtoc13``.
+-
+- Parameters
+- ----------
+- type : const char array
+- ob1 : double array
+- ob2 : double array
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- rc : double array
+- dc : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t o c 1 3
+- - - - - - - - - - -
+-
+- Observed place at a groundbased site to to ICRS astrometric RA,Dec.
+- The caller supplies UTC, site coordinates, ambient air conditions
+- and observing wavelength.
+-
+- Given:
+- type char[] type of coordinates - "R", "H" or "A" (Notes 1,2)
+- ob1 double observed Az, HA or RA (radians; Az is N=0,E=90)
+- ob2 double observed ZD or Dec (radians)
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 3,4)
+- dut1 double UT1-UTC (seconds, Note 5)
+- elong double longitude (radians, east +ve, Note 6)
+- phi double geodetic latitude (radians, Note 6)
+- hm double height above ellipsoid (m, geodetic Notes 6,8)
+- xp,yp double polar motion coordinates (radians, Note 7)
+- phpa double pressure at the observer (hPa = mB, Note 8)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 9)
+-
+- Returned:
+- rc,dc double ICRS astrometric RA,Dec (radians)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 4)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) "Observed" Az,ZD means the position that would be seen by a
+- perfect geodetically aligned theodolite. (Zenith distance is
+- used rather than altitude in order to reflect the fact that no
+- allowance is made for depression of the horizon.) This is
+- related to the observed HA,Dec via the standard rotation, using
+- the geodetic latitude (corrected for polar motion), while the
+- observed HA and RA are related simply through the Earth rotation
+- angle and the site longitude. "Observed" RA,Dec or HA,Dec thus
+- means the position that would be seen by a perfect equatorial
+- with its polar axis aligned to the Earth's axis of rotation.
+-
+- 2) Only the first character of the type argument is significant.
+- "R" or "r" indicates that ob1 and ob2 are the observed right
+- ascension and declination; "H" or "h" indicates that they are
+- hour angle (west +ve) and declination; anything else ("A" or
+- "a" is recommended) indicates that ob1 and ob2 are azimuth
+- (north zero, east 90 deg) and zenith distance.
+-
+- 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 4) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the
+- future to be trusted. See eraDat for further details.
+-
+- 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 6) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 7) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many
+- applications, xp and yp can be set to zero.
+-
+- 8) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB), is
+- available, an adequate estimate of hm can be obtained from the
+- expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to
+- the pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 9) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 10) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted astrometric
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better
+- than 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- Without refraction, the complementary functions eraAtco13 and
+- eraAtoc13 are self-consistent to better than 1 microarcsecond
+- all over the celestial sphere. With refraction included,
+- consistency falls off at high zenith distances, but is still
+- better than 0.05 arcsec at 85 degrees.
+-
+- 11) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- Called:
+- eraApco13 astrometry parameters, ICRS-observed
+- eraAtoiq quick observed to CIRS
+- eraAticq quick CIRS to ICRS
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc, dc, c_retval = ufunc.atoc13(type, ob1, ob2, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'atoc13')
+- return rc, dc
+-
+-
+-STATUS_CODES['atoc13'] = {1: 'dubious year (Note 4)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def atoi13(type, ob1, ob2, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraAtoi13``.
+-
+- Parameters
+- ----------
+- type : const char array
+- ob1 : double array
+- ob2 : double array
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a A t o i 1 3
+- - - - - - - - - - -
+-
+- Observed place to CIRS. The caller supplies UTC, site coordinates,
+- ambient air conditions and observing wavelength.
+-
+- Given:
+- type char[] type of coordinates - "R", "H" or "A" (Notes 1,2)
+- ob1 double observed Az, HA or RA (radians; Az is N=0,E=90)
+- ob2 double observed ZD or Dec (radians)
+- utc1 double UTC as a 2-part...
+- utc2 double ...quasi Julian Date (Notes 3,4)
+- dut1 double UT1-UTC (seconds, Note 5)
+- elong double longitude (radians, east +ve, Note 6)
+- phi double geodetic latitude (radians, Note 6)
+- hm double height above the ellipsoid (meters, Notes 6,8)
+- xp,yp double polar motion coordinates (radians, Note 7)
+- phpa double pressure at the observer (hPa = mB, Note 8)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers, Note 9)
+-
+- Returned:
+- ri double* CIRS right ascension (CIO-based, radians)
+- di double* CIRS declination (radians)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 2)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) "Observed" Az,ZD means the position that would be seen by a
+- perfect geodetically aligned theodolite. (Zenith distance is
+- used rather than altitude in order to reflect the fact that no
+- allowance is made for depression of the horizon.) This is
+- related to the observed HA,Dec via the standard rotation, using
+- the geodetic latitude (corrected for polar motion), while the
+- observed HA and RA are related simply through the Earth rotation
+- angle and the site longitude. "Observed" RA,Dec or HA,Dec thus
+- means the position that would be seen by a perfect equatorial
+- with its polar axis aligned to the Earth's axis of rotation.
+-
+- 2) Only the first character of the type argument is significant.
+- "R" or "r" indicates that ob1 and ob2 are the observed right
+- ascension and declination; "H" or "h" indicates that they are
+- hour angle (west +ve) and declination; anything else ("A" or
+- "a" is recommended) indicates that ob1 and ob2 are azimuth
+- (north zero, east 90 deg) and zenith distance.
+-
+- 3) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- However, JD cannot unambiguously represent UTC during a leap
+- second unless special measures are taken. The convention in the
+- present function is that the JD day represents UTC days whether
+- the length is 86399, 86400 or 86401 SI seconds.
+-
+- Applications should use the function eraDtf2d to convert from
+- calendar date and time of day into 2-part quasi Julian Date, as
+- it implements the leap-second-ambiguity convention just
+- described.
+-
+- 4) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the
+- future to be trusted. See eraDat for further details.
+-
+- 5) UT1-UTC is tabulated in IERS bulletins. It increases by exactly
+- one second at the end of each positive UTC leap second,
+- introduced in order to keep UT1-UTC within +/- 0.9s. n.b. This
+- practice is under review, and in the future UT1-UTC may grow
+- essentially without limit.
+-
+- 6) The geographical coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid. TAKE CARE WITH THE LONGITUDE SIGN: the
+- longitude required by the present function is east-positive
+- (i.e. right-handed), in accordance with geographical convention.
+-
+- 7) The polar motion xp,yp can be obtained from IERS bulletins. The
+- values are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions 2003), measured along the
+- meridians 0 and 90 deg west respectively. For many
+- applications, xp and yp can be set to zero.
+-
+- 8) If hm, the height above the ellipsoid of the observing station
+- in meters, is not known but phpa, the pressure in hPa (=mB), is
+- available, an adequate estimate of hm can be obtained from the
+- expression
+-
+- hm = -29.3 * tsl * log ( phpa / 1013.25 );
+-
+- where tsl is the approximate sea-level air temperature in K
+- (See Astrophysical Quantities, C.W.Allen, 3rd edition, section
+- 52). Similarly, if the pressure phpa is not known, it can be
+- estimated from the height of the observing station, hm, as
+- follows:
+-
+- phpa = 1013.25 * exp ( -hm / ( 29.3 * tsl ) );
+-
+- Note, however, that the refraction is nearly proportional to
+- the pressure and that an accurate phpa value is important for
+- precise work.
+-
+- 9) The argument wl specifies the observing wavelength in
+- micrometers. The transition from optical to radio is assumed to
+- occur at 100 micrometers (about 3000 GHz).
+-
+- 10) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted astrometric
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better
+- than 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- Without refraction, the complementary functions eraAtio13 and
+- eraAtoi13 are self-consistent to better than 1 microarcsecond
+- all over the celestial sphere. With refraction included,
+- consistency falls off at high zenith distances, but is still
+- better than 0.05 arcsec at 85 degrees.
+-
+- 12) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- Called:
+- eraApio13 astrometry parameters, CIRS-observed, 2013
+- eraAtoiq quick observed to CIRS
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di, c_retval = ufunc.atoi13(type, ob1, ob2, utc1, utc2, dut1, elong, phi, hm, xp, yp, phpa, tc, rh, wl)
+- check_errwarn(c_retval, 'atoi13')
+- return ri, di
+-
+-
+-STATUS_CODES['atoi13'] = {1: 'dubious year (Note 2)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def atoiq(type, ob1, ob2, astrom):
+- """
+- Wrapper for ERFA function ``eraAtoiq``.
+-
+- Parameters
+- ----------
+- type : const char array
+- ob1 : double array
+- ob2 : double array
+- astrom : eraASTROM array
+-
+- Returns
+- -------
+- ri : double array
+- di : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a A t o i q
+- - - - - - - - - -
+-
+- Quick observed place to CIRS, given the star-independent astrometry
+- parameters.
+-
+- Use of this function is appropriate when efficiency is important and
+- where many star positions are all to be transformed for one date.
+- The star-independent astrometry parameters can be obtained by
+- calling eraApio[13] or eraApco[13].
+-
+- Given:
+- type char[] type of coordinates: "R", "H" or "A" (Note 1)
+- ob1 double observed Az, HA or RA (radians; Az is N=0,E=90)
+- ob2 double observed ZD or Dec (radians)
+- astrom eraASTROM* star-independent astrometry parameters:
+- pmt double PM time interval (SSB, Julian years)
+- eb double[3] SSB to observer (vector, au)
+- eh double[3] Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+- v double[3] barycentric observer velocity (vector, c)
+- bm1 double sqrt(1-|v|^2): reciprocal of Lorenz factor
+- bpn double[3][3] bias-precession-nutation matrix
+- along double longitude + s' (radians)
+- xpl double polar motion xp wrt local meridian (radians)
+- ypl double polar motion yp wrt local meridian (radians)
+- sphi double sine of geodetic latitude
+- cphi double cosine of geodetic latitude
+- diurab double magnitude of diurnal aberration vector
+- eral double "local" Earth rotation angle (radians)
+- refa double refraction constant A (radians)
+- refb double refraction constant B (radians)
+-
+- Returned:
+- ri double* CIRS right ascension (CIO-based, radians)
+- di double* CIRS declination (radians)
+-
+- Notes:
+-
+- 1) "Observed" Az,El means the position that would be seen by a
+- perfect geodetically aligned theodolite. This is related to
+- the observed HA,Dec via the standard rotation, using the geodetic
+- latitude (corrected for polar motion), while the observed HA and
+- RA are related simply through the Earth rotation angle and the
+- site longitude. "Observed" RA,Dec or HA,Dec thus means the
+- position that would be seen by a perfect equatorial with its
+- polar axis aligned to the Earth's axis of rotation. By removing
+- from the observed place the effects of atmospheric refraction and
+- diurnal aberration, the CIRS RA,Dec is obtained.
+-
+- 2) Only the first character of the type argument is significant.
+- "R" or "r" indicates that ob1 and ob2 are the observed right
+- ascension and declination; "H" or "h" indicates that they are
+- hour angle (west +ve) and declination; anything else ("A" or
+- "a" is recommended) indicates that ob1 and ob2 are azimuth (north
+- zero, east 90 deg) and zenith distance. (Zenith distance is used
+- rather than altitude in order to reflect the fact that no
+- allowance is made for depression of the horizon.)
+-
+- 3) The accuracy of the result is limited by the corrections for
+- refraction, which use a simple A*tan(z) + B*tan^3(z) model.
+- Providing the meteorological parameters are known accurately and
+- there are no gross local effects, the predicted observed
+- coordinates should be within 0.05 arcsec (optical) or 1 arcsec
+- (radio) for a zenith distance of less than 70 degrees, better
+- than 30 arcsec (optical or radio) at 85 degrees and better than
+- 20 arcmin (optical) or 30 arcmin (radio) at the horizon.
+-
+- Without refraction, the complementary functions eraAtioq and
+- eraAtoiq are self-consistent to better than 1 microarcsecond all
+- over the celestial sphere. With refraction included, consistency
+- falls off at high zenith distances, but is still better than
+- 0.05 arcsec at 85 degrees.
+-
+- 4) It is advisable to take great care with units, as even unlikely
+- values of the input parameters are accepted and processed in
+- accordance with the models used.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ri, di = ufunc.atoiq(type, ob1, ob2, astrom)
+- return ri, di
+-
+-
+-def ld(bm, p, q, e, em, dlim):
+- """
+- Wrapper for ERFA function ``eraLd``.
+-
+- Parameters
+- ----------
+- bm : double array
+- p : double array
+- q : double array
+- e : double array
+- em : double array
+- dlim : double array
+-
+- Returns
+- -------
+- p1 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a L d
+- - - - - - -
+-
+- Apply light deflection by a solar-system body, as part of
+- transforming coordinate direction into natural direction.
+-
+- Given:
+- bm double mass of the gravitating body (solar masses)
+- p double[3] direction from observer to source (unit vector)
+- q double[3] direction from body to source (unit vector)
+- e double[3] direction from body to observer (unit vector)
+- em double distance from body to observer (au)
+- dlim double deflection limiter (Note 4)
+-
+- Returned:
+- p1 double[3] observer to deflected source (unit vector)
+-
+- Notes:
+-
+- 1) The algorithm is based on Expr. (70) in Klioner (2003) and
+- Expr. (7.63) in the Explanatory Supplement (Urban & Seidelmann
+- 2013), with some rearrangement to minimize the effects of machine
+- precision.
+-
+- 2) The mass parameter bm can, as required, be adjusted in order to
+- allow for such effects as quadrupole field.
+-
+- 3) The barycentric position of the deflecting body should ideally
+- correspond to the time of closest approach of the light ray to
+- the body.
+-
+- 4) The deflection limiter parameter dlim is phi^2/2, where phi is
+- the angular separation (in radians) between source and body at
+- which limiting is applied. As phi shrinks below the chosen
+- threshold, the deflection is artificially reduced, reaching zero
+- for phi = 0.
+-
+- 5) The returned vector p1 is not normalized, but the consequential
+- departure from unit magnitude is always negligible.
+-
+- 6) The arguments p and p1 can be the same array.
+-
+- 7) To accumulate total light deflection taking into account the
+- contributions from several bodies, call the present function for
+- each body in succession, in decreasing order of distance from the
+- observer.
+-
+- 8) For efficiency, validation is omitted. The supplied vectors must
+- be of unit magnitude, and the deflection limiter non-zero and
+- positive.
+-
+- References:
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013).
+-
+- Klioner, Sergei A., "A practical relativistic model for micro-
+- arcsecond astrometry in space", Astr. J. 125, 1580-1597 (2003).
+-
+- Called:
+- eraPdp scalar product of two p-vectors
+- eraPxp vector product of two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p1 = ufunc.ld(bm, p, q, e, em, dlim)
+- return p1
+-
+-
+-def ldn(b, ob, sc):
+- """
+- Wrapper for ERFA function ``eraLdn``.
+-
+- Parameters
+- ----------
+- b : eraLDBODY array
+- ob : double array
+- sc : double array
+-
+- Returns
+- -------
+- sn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+-/*+
+- - - - - - - -
+- e r a L d n
+- - - - - - - -
+-
+- For a star, apply light deflection by multiple solar-system bodies,
+- as part of transforming coordinate direction into natural direction.
+-
+- Given:
+- n int number of bodies (note 1)
+- b eraLDBODY[n] data for each of the n bodies (Notes 1,2):
+- bm double mass of the body (solar masses, Note 3)
+- dl double deflection limiter (Note 4)
+- pv [2][3] barycentric PV of the body (au, au/day)
+- ob double[3] barycentric position of the observer (au)
+- sc double[3] observer to star coord direction (unit vector)
+-
+- Returned:
+- sn double[3] observer to deflected star (unit vector)
+-
+- 1) The array b contains n entries, one for each body to be
+- considered. If n = 0, no gravitational light deflection will be
+- applied, not even for the Sun.
+-
+- 2) The array b should include an entry for the Sun as well as for
+- any planet or other body to be taken into account. The entries
+- should be in the order in which the light passes the body.
+-
+- 3) In the entry in the b array for body i, the mass parameter
+- b[i].bm can, as required, be adjusted in order to allow for such
+- effects as quadrupole field.
+-
+- 4) The deflection limiter parameter b[i].dl is phi^2/2, where phi is
+- the angular separation (in radians) between star and body at
+- which limiting is applied. As phi shrinks below the chosen
+- threshold, the deflection is artificially reduced, reaching zero
+- for phi = 0. Example values suitable for a terrestrial
+- observer, together with masses, are as follows:
+-
+- body i b[i].bm b[i].dl
+-
+- Sun 1.0 6e-6
+- Jupiter 0.00095435 3e-9
+- Saturn 0.00028574 3e-10
+-
+- 5) For cases where the starlight passes the body before reaching the
+- observer, the body is placed back along its barycentric track by
+- the light time from that point to the observer. For cases where
+- the body is "behind" the observer no such shift is applied. If
+- a different treatment is preferred, the user has the option of
+- instead using the eraLd function. Similarly, eraLd can be used
+- for cases where the source is nearby, not a star.
+-
+- 6) The returned vector sn is not normalized, but the consequential
+- departure from unit magnitude is always negligible.
+-
+- 7) The arguments sc and sn can be the same array.
+-
+- 8) For efficiency, validation is omitted. The supplied masses must
+- be greater than zero, the position and velocity vectors must be
+- right, and the deflection limiter greater than zero.
+-
+- Reference:
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013), Section 7.2.4.
+-
+- Called:
+- eraCp copy p-vector
+- eraPdp scalar product of two p-vectors
+- eraPmp p-vector minus p-vector
+- eraPpsp p-vector plus scaled p-vector
+- eraPn decompose p-vector into modulus and direction
+- eraLd light deflection by a solar-system body
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- sn = ufunc.ldn(b, ob, sc)
+- return sn
+-
+-
+-def ldsun(p, e, em):
+- """
+- Wrapper for ERFA function ``eraLdsun``.
+-
+- Parameters
+- ----------
+- p : double array
+- e : double array
+- em : double array
+-
+- Returns
+- -------
+- p1 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a L d s u n
+- - - - - - - - - -
+-
+- Deflection of starlight by the Sun.
+-
+- Given:
+- p double[3] direction from observer to star (unit vector)
+- e double[3] direction from Sun to observer (unit vector)
+- em double distance from Sun to observer (au)
+-
+- Returned:
+- p1 double[3] observer to deflected star (unit vector)
+-
+- Notes:
+-
+- 1) The source is presumed to be sufficiently distant that its
+- directions seen from the Sun and the observer are essentially
+- the same.
+-
+- 2) The deflection is restrained when the angle between the star and
+- the center of the Sun is less than a threshold value, falling to
+- zero deflection for zero separation. The chosen threshold value
+- is within the solar limb for all solar-system applications, and
+- is about 5 arcminutes for the case of a terrestrial observer.
+-
+- 3) The arguments p and p1 can be the same array.
+-
+- Called:
+- eraLd light deflection by a solar-system body
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p1 = ufunc.ldsun(p, e, em)
+- return p1
+-
+-
+-def pmpx(rc, dc, pr, pd, px, rv, pmt, pob):
+- """
+- Wrapper for ERFA function ``eraPmpx``.
+-
+- Parameters
+- ----------
+- rc : double array
+- dc : double array
+- pr : double array
+- pd : double array
+- px : double array
+- rv : double array
+- pmt : double array
+- pob : double array
+-
+- Returns
+- -------
+- pco : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P m p x
+- - - - - - - - -
+-
+- Proper motion and parallax.
+-
+- Given:
+- rc,dc double ICRS RA,Dec at catalog epoch (radians)
+- pr double RA proper motion (radians/year; Note 1)
+- pd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, +ve if receding)
+- pmt double proper motion time interval (SSB, Julian years)
+- pob double[3] SSB to observer vector (au)
+-
+- Returned:
+- pco double[3] coordinate direction (BCRS unit vector)
+-
+- Notes:
+-
+- 1) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- 2) The proper motion time interval is for when the starlight
+- reaches the solar system barycenter.
+-
+- 3) To avoid the need for iteration, the Roemer effect (i.e. the
+- small annual modulation of the proper motion coming from the
+- changing light time) is applied approximately, using the
+- direction of the star at the catalog epoch.
+-
+- References:
+-
+- 1984 Astronomical Almanac, pp B39-B41.
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013), Section 7.2.
+-
+- Called:
+- eraPdp scalar product of two p-vectors
+- eraPn decompose p-vector into modulus and direction
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pco = ufunc.pmpx(rc, dc, pr, pd, px, rv, pmt, pob)
+- return pco
+-
+-
+-def pmsafe(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b):
+- """
+- Wrapper for ERFA function ``eraPmsafe``.
+-
+- Parameters
+- ----------
+- ra1 : double array
+- dec1 : double array
+- pmr1 : double array
+- pmd1 : double array
+- px1 : double array
+- rv1 : double array
+- ep1a : double array
+- ep1b : double array
+- ep2a : double array
+- ep2b : double array
+-
+- Returns
+- -------
+- ra2 : double array
+- dec2 : double array
+- pmr2 : double array
+- pmd2 : double array
+- px2 : double array
+- rv2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P m s a f e
+- - - - - - - - - - -
+-
+- Star proper motion: update star catalog data for space motion, with
+- special handling to handle the zero parallax case.
+-
+- Given:
+- ra1 double right ascension (radians), before
+- dec1 double declination (radians), before
+- pmr1 double RA proper motion (radians/year), before
+- pmd1 double Dec proper motion (radians/year), before
+- px1 double parallax (arcseconds), before
+- rv1 double radial velocity (km/s, +ve = receding), before
+- ep1a double "before" epoch, part A (Note 1)
+- ep1b double "before" epoch, part B (Note 1)
+- ep2a double "after" epoch, part A (Note 1)
+- ep2b double "after" epoch, part B (Note 1)
+-
+- Returned:
+- ra2 double right ascension (radians), after
+- dec2 double declination (radians), after
+- pmr2 double RA proper motion (radians/year), after
+- pmd2 double Dec proper motion (radians/year), after
+- px2 double parallax (arcseconds), after
+- rv2 double radial velocity (km/s, +ve = receding), after
+-
+- Returned (function value):
+- int status:
+- -1 = system error (should not occur)
+- 0 = no warnings or errors
+- 1 = distance overridden (Note 6)
+- 2 = excessive velocity (Note 7)
+- 4 = solution didn't converge (Note 8)
+- else = binary logical OR of the above warnings
+-
+- Notes:
+-
+- 1) The starting and ending TDB epochs ep1a+ep1b and ep2a+ep2b are
+- Julian Dates, apportioned in any convenient way between the two
+- parts (A and B). For example, JD(TDB)=2450123.7 could be
+- expressed in any of these ways, among others:
+-
+- epNa epNb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience.
+-
+- 2) In accordance with normal star-catalog conventions, the object's
+- right ascension and declination are freed from the effects of
+- secular aberration. The frame, which is aligned to the catalog
+- equator and equinox, is Lorentzian and centered on the SSB.
+-
+- The proper motions are the rate of change of the right ascension
+- and declination at the catalog epoch and are in radians per TDB
+- Julian year.
+-
+- The parallax and radial velocity are in the same frame.
+-
+- 3) Care is needed with units. The star coordinates are in radians
+- and the proper motions in radians per Julian year, but the
+- parallax is in arcseconds.
+-
+- 4) The RA proper motion is in terms of coordinate angle, not true
+- angle. If the catalog uses arcseconds for both RA and Dec proper
+- motions, the RA proper motion will need to be divided by cos(Dec)
+- before use.
+-
+- 5) Straight-line motion at constant speed, in the inertial frame, is
+- assumed.
+-
+- 6) An extremely small (or zero or negative) parallax is overridden
+- to ensure that the object is at a finite but very large distance,
+- but not so large that the proper motion is equivalent to a large
+- but safe speed (about 0.1c using the chosen constant). A warning
+- status of 1 is added to the status if this action has been taken.
+-
+- 7) If the space velocity is a significant fraction of c (see the
+- constant VMAX in the function eraStarpv), it is arbitrarily set
+- to zero. When this action occurs, 2 is added to the status.
+-
+- 8) The relativistic adjustment carried out in the eraStarpv function
+- involves an iterative calculation. If the process fails to
+- converge within a set number of iterations, 4 is added to the
+- status.
+-
+- Called:
+- eraSeps angle between two points
+- eraStarpm update star catalog data for space motion
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ra2, dec2, pmr2, pmd2, px2, rv2, c_retval = ufunc.pmsafe(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b)
+- check_errwarn(c_retval, 'pmsafe')
+- return ra2, dec2, pmr2, pmd2, px2, rv2
+-
+-
+-STATUS_CODES['pmsafe'] = {-1: 'system error (should not occur)', 0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above warnings'}
+-
+-
+-def pvtob(elong, phi, hm, xp, yp, sp, theta):
+- """
+- Wrapper for ERFA function ``eraPvtob``.
+-
+- Parameters
+- ----------
+- elong : double array
+- phi : double array
+- hm : double array
+- xp : double array
+- yp : double array
+- sp : double array
+- theta : double array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v t o b
+- - - - - - - - - -
+-
+- Position and velocity of a terrestrial observing station.
+-
+- Given:
+- elong double longitude (radians, east +ve, Note 1)
+- phi double latitude (geodetic, radians, Note 1)
+- hm double height above ref. ellipsoid (geodetic, m)
+- xp,yp double coordinates of the pole (radians, Note 2)
+- sp double the TIO locator s' (radians, Note 2)
+- theta double Earth rotation angle (radians, Note 3)
+-
+- Returned:
+- pv double[2][3] position/velocity vector (m, m/s, CIRS)
+-
+- Notes:
+-
+- 1) The terrestrial coordinates are with respect to the ERFA_WGS84
+- reference ellipsoid.
+-
+- 2) xp and yp are the coordinates (in radians) of the Celestial
+- Intermediate Pole with respect to the International Terrestrial
+- Reference System (see IERS Conventions), measured along the
+- meridians 0 and 90 deg west respectively. sp is the TIO locator
+- s', in radians, which positions the Terrestrial Intermediate
+- Origin on the equator. For many applications, xp, yp and
+- (especially) sp can be set to zero.
+-
+- 3) If theta is Greenwich apparent sidereal time instead of Earth
+- rotation angle, the result is with respect to the true equator
+- and equinox of date, i.e. with the x-axis at the equinox rather
+- than the celestial intermediate origin.
+-
+- 4) The velocity units are meters per UT1 second, not per SI second.
+- This is unlikely to have any practical consequences in the modern
+- era.
+-
+- 5) No validation is performed on the arguments. Error cases that
+- could lead to arithmetic exceptions are trapped by the eraGd2gc
+- function, and the result set to zeros.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to
+- the Astronomical Almanac, 3rd ed., University Science Books
+- (2013), Section 7.4.3.3.
+-
+- Called:
+- eraGd2gc geodetic to geocentric transformation
+- eraPom00 polar motion matrix
+- eraTrxp product of transpose of r-matrix and p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv = ufunc.pvtob(elong, phi, hm, xp, yp, sp, theta)
+- return pv
+-
+-
+-def refco(phpa, tc, rh, wl):
+- """
+- Wrapper for ERFA function ``eraRefco``.
+-
+- Parameters
+- ----------
+- phpa : double array
+- tc : double array
+- rh : double array
+- wl : double array
+-
+- Returns
+- -------
+- refa : double array
+- refb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a R e f c o
+- - - - - - - - - -
+-
+- Determine the constants A and B in the atmospheric refraction model
+- dZ = A tan Z + B tan^3 Z.
+-
+- Z is the "observed" zenith distance (i.e. affected by refraction)
+- and dZ is what to add to Z to give the "topocentric" (i.e. in vacuo)
+- zenith distance.
+-
+- Given:
+- phpa double pressure at the observer (hPa = millibar)
+- tc double ambient temperature at the observer (deg C)
+- rh double relative humidity at the observer (range 0-1)
+- wl double wavelength (micrometers)
+-
+- Returned:
+- refa double* tan Z coefficient (radians)
+- refb double* tan^3 Z coefficient (radians)
+-
+- Notes:
+-
+- 1) The model balances speed and accuracy to give good results in
+- applications where performance at low altitudes is not paramount.
+- Performance is maintained across a range of conditions, and
+- applies to both optical/IR and radio.
+-
+- 2) The model omits the effects of (i) height above sea level (apart
+- from the reduced pressure itself), (ii) latitude (i.e. the
+- flattening of the Earth), (iii) variations in tropospheric lapse
+- rate and (iv) dispersive effects in the radio.
+-
+- The model was tested using the following range of conditions:
+-
+- lapse rates 0.0055, 0.0065, 0.0075 deg/meter
+- latitudes 0, 25, 50, 75 degrees
+- heights 0, 2500, 5000 meters ASL
+- pressures mean for height -10% to +5% in steps of 5%
+- temperatures -10 deg to +20 deg with respect to 280 deg at SL
+- relative humidity 0, 0.5, 1
+- wavelengths 0.4, 0.6, ... 2 micron, + radio
+- zenith distances 15, 45, 75 degrees
+-
+- The accuracy with respect to raytracing through a model
+- atmosphere was as follows:
+-
+- worst RMS
+-
+- optical/IR 62 mas 8 mas
+- radio 319 mas 49 mas
+-
+- For this particular set of conditions:
+-
+- lapse rate 0.0065 K/meter
+- latitude 50 degrees
+- sea level
+- pressure 1005 mb
+- temperature 280.15 K
+- humidity 80%
+- wavelength 5740 Angstroms
+-
+- the results were as follows:
+-
+- ZD raytrace eraRefco Saastamoinen
+-
+- 10 10.27 10.27 10.27
+- 20 21.19 21.20 21.19
+- 30 33.61 33.61 33.60
+- 40 48.82 48.83 48.81
+- 45 58.16 58.18 58.16
+- 50 69.28 69.30 69.27
+- 55 82.97 82.99 82.95
+- 60 100.51 100.54 100.50
+- 65 124.23 124.26 124.20
+- 70 158.63 158.68 158.61
+- 72 177.32 177.37 177.31
+- 74 200.35 200.38 200.32
+- 76 229.45 229.43 229.42
+- 78 267.44 267.29 267.41
+- 80 319.13 318.55 319.10
+-
+- deg arcsec arcsec arcsec
+-
+- The values for Saastamoinen's formula (which includes terms
+- up to tan^5) are taken from Hohenkerk and Sinclair (1985).
+-
+- 3) A wl value in the range 0-100 selects the optical/IR case and is
+- wavelength in micrometers. Any value outside this range selects
+- the radio case.
+-
+- 4) Outlandish input parameters are silently limited to
+- mathematically safe values. Zero pressure is permissible, and
+- causes zeroes to be returned.
+-
+- 5) The algorithm draws on several sources, as follows:
+-
+- a) The formula for the saturation vapour pressure of water as
+- a function of temperature and temperature is taken from
+- Equations (A4.5-A4.7) of Gill (1982).
+-
+- b) The formula for the water vapour pressure, given the
+- saturation pressure and the relative humidity, is from
+- Crane (1976), Equation (2.5.5).
+-
+- c) The refractivity of air is a function of temperature,
+- total pressure, water-vapour pressure and, in the case
+- of optical/IR, wavelength. The formulae for the two cases are
+- developed from Hohenkerk & Sinclair (1985) and Rueger (2002).
+-
+- d) The formula for beta, the ratio of the scale height of the
+- atmosphere to the geocentric distance of the observer, is
+- an adaption of Equation (9) from Stone (1996). The
+- adaptations, arrived at empirically, consist of (i) a small
+- adjustment to the coefficient and (ii) a humidity term for the
+- radio case only.
+-
+- e) The formulae for the refraction constants as a function of
+- n-1 and beta are from Green (1987), Equation (4.31).
+-
+- References:
+-
+- Crane, R.K., Meeks, M.L. (ed), "Refraction Effects in the Neutral
+- Atmosphere", Methods of Experimental Physics: Astrophysics 12B,
+- Academic Press, 1976.
+-
+- Gill, Adrian E., "Atmosphere-Ocean Dynamics", Academic Press,
+- 1982.
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987.
+-
+- Hohenkerk, C.Y., & Sinclair, A.T., NAO Technical Note No. 63,
+- 1985.
+-
+- Rueger, J.M., "Refractive Index Formulae for Electronic Distance
+- Measurement with Radio and Millimetre Waves", in Unisurv Report
+- S-68, School of Surveying and Spatial Information Systems,
+- University of New South Wales, Sydney, Australia, 2002.
+-
+- Stone, Ronald C., P.A.S.P. 108, 1051-1058, 1996.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- refa, refb = ufunc.refco(phpa, tc, rh, wl)
+- return refa, refb
+-
+-
+-def epv00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEpv00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- pvh : double array
+- pvb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E p v 0 0
+- - - - - - - - - -
+-
+- Earth position and velocity, heliocentric and barycentric, with
+- respect to the Barycentric Celestial Reference System.
+-
+- Given:
+- date1,date2 double TDB date (Note 1)
+-
+- Returned:
+- pvh double[2][3] heliocentric Earth position/velocity
+- pvb double[2][3] barycentric Earth position/velocity
+-
+- Returned (function value):
+- int status: 0 = OK
+- +1 = warning: date outside
+- the range 1900-2100 AD
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. However,
+- the accuracy of the result is more likely to be limited by the
+- algorithm itself than the way the date has been expressed.
+-
+- n.b. TT can be used instead of TDB in most applications.
+-
+- 2) On return, the arrays pvh and pvb contain the following:
+-
+- pvh[0][0] x }
+- pvh[0][1] y } heliocentric position, au
+- pvh[0][2] z }
+-
+- pvh[1][0] xdot }
+- pvh[1][1] ydot } heliocentric velocity, au/d
+- pvh[1][2] zdot }
+-
+- pvb[0][0] x }
+- pvb[0][1] y } barycentric position, au
+- pvb[0][2] z }
+-
+- pvb[1][0] xdot }
+- pvb[1][1] ydot } barycentric velocity, au/d
+- pvb[1][2] zdot }
+-
+- The vectors are with respect to the Barycentric Celestial
+- Reference System. The time unit is one day in TDB.
+-
+- 3) The function is a SIMPLIFIED SOLUTION from the planetary theory
+- VSOP2000 (X. Moisson, P. Bretagnon, 2001, Celes. Mechanics &
+- Dyn. Astron., 80, 3/4, 205-213) and is an adaptation of original
+- Fortran code supplied by P. Bretagnon (private comm., 2000).
+-
+- 4) Comparisons over the time span 1900-2100 with this simplified
+- solution and the JPL DE405 ephemeris give the following results:
+-
+- RMS max
+- Heliocentric:
+- position error 3.7 11.2 km
+- velocity error 1.4 5.0 mm/s
+-
+- Barycentric:
+- position error 4.6 13.4 km
+- velocity error 1.4 4.9 mm/s
+-
+- Comparisons with the JPL DE406 ephemeris show that by 1800 and
+- 2200 the position errors are approximately double their 1900-2100
+- size. By 1500 and 2500 the deterioration is a factor of 10 and
+- by 1000 and 3000 a factor of 60. The velocity accuracy falls off
+- at about half that rate.
+-
+- 5) It is permissible to use the same array for pvh and pvb, which
+- will receive the barycentric values.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pvh, pvb, c_retval = ufunc.epv00(date1, date2)
+- check_errwarn(c_retval, 'epv00')
+- return pvh, pvb
+-
+-
+-STATUS_CODES['epv00'] = {0: 'OK', 1: 'warning: date outsidethe range 1900-2100 AD'}
+-
+-
+-def plan94(date1, date2, np):
+- """
+- Wrapper for ERFA function ``eraPlan94``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- np : int array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P l a n 9 4
+- - - - - - - - - - -
+-
+- Approximate heliocentric position and velocity of a nominated major
+- planet: Mercury, Venus, EMB, Mars, Jupiter, Saturn, Uranus or
+- Neptune (but not the Earth itself).
+-
+- Given:
+- date1 double TDB date part A (Note 1)
+- date2 double TDB date part B (Note 1)
+- np int planet (1=Mercury, 2=Venus, 3=EMB, 4=Mars,
+- 5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune)
+-
+- Returned (argument):
+- pv double[2][3] planet p,v (heliocentric, J2000.0, au,au/d)
+-
+- Returned (function value):
+- int status: -1 = illegal NP (outside 1-8)
+- 0 = OK
+- +1 = warning: year outside 1000-3000
+- +2 = warning: failed to converge
+-
+- Notes:
+-
+- 1) The date date1+date2 is in the TDB time scale (in practice TT can
+- be used) and is a Julian Date, apportioned in any convenient way
+- between the two arguments. For example, JD(TDB)=2450123.7 could
+- be expressed in any of these ways, among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- resolution. The MJD method and the date & time methods are both
+- good compromises between resolution and convenience. The limited
+- accuracy of the present algorithm is such that any of the methods
+- is satisfactory.
+-
+- 2) If an np value outside the range 1-8 is supplied, an error status
+- (function value -1) is returned and the pv vector set to zeroes.
+-
+- 3) For np=3 the result is for the Earth-Moon Barycenter. To obtain
+- the heliocentric position and velocity of the Earth, use instead
+- the ERFA function eraEpv00.
+-
+- 4) On successful return, the array pv contains the following:
+-
+- pv[0][0] x }
+- pv[0][1] y } heliocentric position, au
+- pv[0][2] z }
+-
+- pv[1][0] xdot }
+- pv[1][1] ydot } heliocentric velocity, au/d
+- pv[1][2] zdot }
+-
+- The reference frame is equatorial and is with respect to the
+- mean equator and equinox of epoch J2000.0.
+-
+- 5) The algorithm is due to J.L. Simon, P. Bretagnon, J. Chapront,
+- M. Chapront-Touze, G. Francou and J. Laskar (Bureau des
+- Longitudes, Paris, France). From comparisons with JPL
+- ephemeris DE102, they quote the following maximum errors
+- over the interval 1800-2050:
+-
+- L (arcsec) B (arcsec) R (km)
+-
+- Mercury 4 1 300
+- Venus 5 1 800
+- EMB 6 1 1000
+- Mars 17 1 7700
+- Jupiter 71 5 76000
+- Saturn 81 13 267000
+- Uranus 86 7 712000
+- Neptune 11 1 253000
+-
+- Over the interval 1000-3000, they report that the accuracy is no
+- worse than 1.5 times that over 1800-2050. Outside 1000-3000 the
+- accuracy declines.
+-
+- Comparisons of the present function with the JPL DE200 ephemeris
+- give the following RMS errors over the interval 1960-2025:
+-
+- position (km) velocity (m/s)
+-
+- Mercury 334 0.437
+- Venus 1060 0.855
+- EMB 2010 0.815
+- Mars 7690 1.98
+- Jupiter 71700 7.70
+- Saturn 199000 19.4
+- Uranus 564000 16.4
+- Neptune 158000 14.4
+-
+- Comparisons against DE200 over the interval 1800-2100 gave the
+- following maximum absolute differences. (The results using
+- DE406 were essentially the same.)
+-
+- L (arcsec) B (arcsec) R (km) Rdot (m/s)
+-
+- Mercury 7 1 500 0.7
+- Venus 7 1 1100 0.9
+- EMB 9 1 1300 1.0
+- Mars 26 1 9000 2.5
+- Jupiter 78 6 82000 8.2
+- Saturn 87 14 263000 24.6
+- Uranus 86 7 661000 27.4
+- Neptune 11 2 248000 21.4
+-
+- 6) The present ERFA re-implementation of the original Simon et al.
+- Fortran code differs from the original in the following respects:
+-
+- * C instead of Fortran.
+-
+- * The date is supplied in two parts.
+-
+- * The result is returned only in equatorial Cartesian form;
+- the ecliptic longitude, latitude and radius vector are not
+- returned.
+-
+- * The result is in the J2000.0 equatorial frame, not ecliptic.
+-
+- * More is done in-line: there are fewer calls to subroutines.
+-
+- * Different error/warning status values are used.
+-
+- * A different Kepler's-equation-solver is used (avoiding
+- use of double precision complex).
+-
+- * Polynomials in t are nested to minimize rounding errors.
+-
+- * Explicit double constants are used to avoid mixed-mode
+- expressions.
+-
+- None of the above changes affects the result significantly.
+-
+- 7) The returned status indicates the most serious condition
+- encountered during execution of the function. Illegal np is
+- considered the most serious, overriding failure to converge,
+- which in turn takes precedence over the remote date warning.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Reference: Simon, J.L, Bretagnon, P., Chapront, J.,
+- Chapront-Touze, M., Francou, G., and Laskar, J.,
+- Astron.Astrophys., 282, 663 (1994).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv, c_retval = ufunc.plan94(date1, date2, np)
+- check_errwarn(c_retval, 'plan94')
+- return pv
+-
+-
+-STATUS_CODES['plan94'] = {-1: 'illegal NP (outside 1-8)', 0: 'OK', 1: 'warning: year outside 1000-3000', 2: 'warning: failed to converge'}
+-
+-
+-def fad03(t):
+- """
+- Wrapper for ERFA function ``eraFad03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F a d 0 3
+- - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean elongation of the Moon from the Sun.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double D, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fad03(t)
+- return c_retval
+-
+-
+-def fae03(t):
+- """
+- Wrapper for ERFA function ``eraFae03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F a e 0 3
+- - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Earth.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Earth, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fae03(t)
+- return c_retval
+-
+-
+-def faf03(t):
+- """
+- Wrapper for ERFA function ``eraFaf03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F a f 0 3
+- - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of the Moon minus mean longitude of the ascending
+- node.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double F, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.faf03(t)
+- return c_retval
+-
+-
+-def faju03(t):
+- """
+- Wrapper for ERFA function ``eraFaju03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a j u 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Jupiter.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Jupiter, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.faju03(t)
+- return c_retval
+-
+-
+-def fal03(t):
+- """
+- Wrapper for ERFA function ``eraFal03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F a l 0 3
+- - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean anomaly of the Moon.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double l, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fal03(t)
+- return c_retval
+-
+-
+-def falp03(t):
+- """
+- Wrapper for ERFA function ``eraFalp03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a l p 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean anomaly of the Sun.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double l', radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.falp03(t)
+- return c_retval
+-
+-
+-def fama03(t):
+- """
+- Wrapper for ERFA function ``eraFama03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a m a 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Mars.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Mars, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fama03(t)
+- return c_retval
+-
+-
+-def fame03(t):
+- """
+- Wrapper for ERFA function ``eraFame03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a m e 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Mercury.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Mercury, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fame03(t)
+- return c_retval
+-
+-
+-def fane03(t):
+- """
+- Wrapper for ERFA function ``eraFane03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a n e 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Neptune.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Neptune, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is adapted from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fane03(t)
+- return c_retval
+-
+-
+-def faom03(t):
+- """
+- Wrapper for ERFA function ``eraFaom03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a o m 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of the Moon's ascending node.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double Omega, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.faom03(t)
+- return c_retval
+-
+-
+-def fapa03(t):
+- """
+- Wrapper for ERFA function ``eraFapa03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a p a 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- general accumulated precession in longitude.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double general precession in longitude, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003). It
+- is taken from Kinoshita & Souchay (1990) and comes originally
+- from Lieske et al. (1977).
+-
+- References:
+-
+- Kinoshita, H. and Souchay J. 1990, Celest.Mech. and Dyn.Astron.
+- 48, 187
+-
+- Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977,
+- Astron.Astrophys. 58, 1-16
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fapa03(t)
+- return c_retval
+-
+-
+-def fasa03(t):
+- """
+- Wrapper for ERFA function ``eraFasa03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a s a 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Saturn.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Saturn, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fasa03(t)
+- return c_retval
+-
+-
+-def faur03(t):
+- """
+- Wrapper for ERFA function ``eraFaur03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a u r 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Uranus.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Uranus, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- is adapted from Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.faur03(t)
+- return c_retval
+-
+-
+-def fave03(t):
+- """
+- Wrapper for ERFA function ``eraFave03``.
+-
+- Parameters
+- ----------
+- t : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F a v e 0 3
+- - - - - - - - - - -
+-
+- Fundamental argument, IERS Conventions (2003):
+- mean longitude of Venus.
+-
+- Given:
+- t double TDB, Julian centuries since J2000.0 (Note 1)
+-
+- Returned (function value):
+- double mean longitude of Venus, radians (Note 2)
+-
+- Notes:
+-
+- 1) Though t is strictly TDB, it is usually more convenient to use
+- TT, which makes no significant difference.
+-
+- 2) The expression used is as adopted in IERS Conventions (2003) and
+- comes from Souchay et al. (1999) after Simon et al. (1994).
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.fave03(t)
+- return c_retval
+-
+-
+-def bi00():
+- """
+- Wrapper for ERFA function ``eraBi00``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- dpsibi : double array
+- depsbi : double array
+- dra : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a B i 0 0
+- - - - - - - - -
+-
+- Frame bias components of IAU 2000 precession-nutation models (part
+- of MHB2000 with additions).
+-
+- Returned:
+- dpsibi,depsbi double longitude and obliquity corrections
+- dra double the ICRS RA of the J2000.0 mean equinox
+-
+- Notes:
+-
+- 1) The frame bias corrections in longitude and obliquity (radians)
+- are required in order to correct for the offset between the GCRS
+- pole and the mean J2000.0 pole. They define, with respect to the
+- GCRS frame, a J2000.0 mean pole that is consistent with the rest
+- of the IAU 2000A precession-nutation model.
+-
+- 2) In addition to the displacement of the pole, the complete
+- description of the frame bias requires also an offset in right
+- ascension. This is not part of the IAU 2000A model, and is from
+- Chapront et al. (2002). It is returned in radians.
+-
+- 3) This is a supplemented implementation of one aspect of the IAU
+- 2000A nutation model, formally adopted by the IAU General
+- Assembly in 2000, namely MHB2000 (Mathews et al. 2002).
+-
+- References:
+-
+- Chapront, J., Chapront-Touze, M. & Francou, G., Astron.
+- Astrophys., 387, 700, 2002.
+-
+- Mathews, P.M., Herring, T.A., Buffet, B.A., "Modeling of nutation
+- and precession New nutation series for nonrigid Earth and
+- insights into the Earth's interior", J.Geophys.Res., 107, B4,
+- 2002. The MHB2000 code itself was obtained on 9th September 2002
+- from ftp://maia.usno.navy.mil/conv2000/chapter5/IAU2000A.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsibi, depsbi, dra = ufunc.bi00()
+- return dpsibi, depsbi, dra
+-
+-
+-def bp00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraBp00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rb : double array
+- rp : double array
+- rbp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a B p 0 0
+- - - - - - - - -
+-
+- Frame bias and precession, IAU 2000.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rb double[3][3] frame bias matrix (Note 2)
+- rp double[3][3] precession matrix (Note 3)
+- rbp double[3][3] bias-precession matrix (Note 4)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rb transforms vectors from GCRS to mean J2000.0 by
+- applying frame bias.
+-
+- 3) The matrix rp transforms vectors from J2000.0 mean equator and
+- equinox to mean equator and equinox of date by applying
+- precession.
+-
+- 4) The matrix rbp transforms vectors from GCRS to mean equator and
+- equinox of date by applying frame bias then precession. It is
+- the product rp x rb.
+-
+- 5) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the order given.
+-
+- Called:
+- eraBi00 frame bias components, IAU 2000
+- eraPr00 IAU 2000 precession adjustments
+- eraIr initialize r-matrix to identity
+- eraRx rotate around X-axis
+- eraRy rotate around Y-axis
+- eraRz rotate around Z-axis
+- eraCr copy r-matrix
+- eraRxr product of two r-matrices
+-
+- Reference:
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rb, rp, rbp = ufunc.bp00(date1, date2)
+- return rb, rp, rbp
+-
+-
+-def bp06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraBp06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rb : double array
+- rp : double array
+- rbp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a B p 0 6
+- - - - - - - - -
+-
+- Frame bias and precession, IAU 2006.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rb double[3][3] frame bias matrix (Note 2)
+- rp double[3][3] precession matrix (Note 3)
+- rbp double[3][3] bias-precession matrix (Note 4)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rb transforms vectors from GCRS to mean J2000.0 by
+- applying frame bias.
+-
+- 3) The matrix rp transforms vectors from mean J2000.0 to mean of
+- date by applying precession.
+-
+- 4) The matrix rbp transforms vectors from GCRS to mean of date by
+- applying frame bias then precession. It is the product rp x rb.
+-
+- 5) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the order given.
+-
+- Called:
+- eraPfw06 bias-precession F-W angles, IAU 2006
+- eraFw2m F-W angles to r-matrix
+- eraPmat06 PB matrix, IAU 2006
+- eraTr transpose r-matrix
+- eraRxr product of two r-matrices
+- eraCr copy r-matrix
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rb, rp, rbp = ufunc.bp06(date1, date2)
+- return rb, rp, rbp
+-
+-
+-def bpn2xy(rbpn):
+- """
+- Wrapper for ERFA function ``eraBpn2xy``.
+-
+- Parameters
+- ----------
+- rbpn : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a B p n 2 x y
+- - - - - - - - - - -
+-
+- Extract from the bias-precession-nutation matrix the X,Y coordinates
+- of the Celestial Intermediate Pole.
+-
+- Given:
+- rbpn double[3][3] celestial-to-true matrix (Note 1)
+-
+- Returned:
+- x,y double Celestial Intermediate Pole (Note 2)
+-
+- Notes:
+-
+- 1) The matrix rbpn transforms vectors from GCRS to true equator (and
+- CIO or equinox) of date, and therefore the Celestial Intermediate
+- Pole unit vector is the bottom row of the matrix.
+-
+- 2) The arguments x,y are components of the Celestial Intermediate
+- Pole unit vector in the Geocentric Celestial Reference System.
+-
+- Reference:
+-
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154
+- (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y = ufunc.bpn2xy(rbpn)
+- return x, y
+-
+-
+-def c2i00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraC2i00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 i 0 0 a
+- - - - - - - - - - -
+-
+- Form the celestial-to-intermediate matrix for a given date using the
+- IAU 2000A precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- 3) A faster, but slightly less accurate result (about 1 mas), can be
+- obtained by using instead the eraC2i00b function.
+-
+- Called:
+- eraPnm00a classical NPB matrix, IAU 2000A
+- eraC2ibpn celestial-to-intermediate matrix, given NPB matrix
+-
+- References:
+-
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154
+- (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2i00a(date1, date2)
+- return rc2i
+-
+-
+-def c2i00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraC2i00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 i 0 0 b
+- - - - - - - - - - -
+-
+- Form the celestial-to-intermediate matrix for a given date using the
+- IAU 2000B precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- 3) The present function is faster, but slightly less accurate (about
+- 1 mas), than the eraC2i00a function.
+-
+- Called:
+- eraPnm00b classical NPB matrix, IAU 2000B
+- eraC2ibpn celestial-to-intermediate matrix, given NPB matrix
+-
+- References:
+-
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154
+- (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2i00b(date1, date2)
+- return rc2i
+-
+-
+-def c2i06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraC2i06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 i 0 6 a
+- - - - - - - - - - -
+-
+- Form the celestial-to-intermediate matrix for a given date using the
+- IAU 2006 precession and IAU 2000A nutation models.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = RC2T * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- Called:
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+- eraC2ixys celestial-to-intermediate matrix, given X,Y and s
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2i06a(date1, date2)
+- return rc2i
+-
+-
+-def c2ibpn(date1, date2, rbpn):
+- """
+- Wrapper for ERFA function ``eraC2ibpn``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- rbpn : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 i b p n
+- - - - - - - - - - -
+-
+- Form the celestial-to-intermediate matrix for a given date given
+- the bias-precession-nutation matrix. IAU 2000.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- rbpn double[3][3] celestial-to-true matrix (Note 2)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 3)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix rbpn transforms vectors from GCRS to true equator (and
+- CIO or equinox) of date. Only the CIP (bottom row) is used.
+-
+- 3) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = RC2T * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- 4) Although its name does not include "00", This function is in fact
+- specific to the IAU 2000 models.
+-
+- Called:
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraC2ixy celestial-to-intermediate matrix, given X,Y
+-
+- References:
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2ibpn(date1, date2, rbpn)
+- return rc2i
+-
+-
+-def c2ixy(date1, date2, x, y):
+- """
+- Wrapper for ERFA function ``eraC2ixy``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- x : double array
+- y : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a C 2 i x y
+- - - - - - - - - -
+-
+- Form the celestial to intermediate-frame-of-date matrix for a given
+- date when the CIP X,Y coordinates are known. IAU 2000.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- x,y double Celestial Intermediate Pole (Note 2)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 3)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The Celestial Intermediate Pole coordinates are the x,y components
+- of the unit vector in the Geocentric Celestial Reference System.
+-
+- 3) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = RC2T * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- 4) Although its name does not include "00", This function is in fact
+- specific to the IAU 2000 models.
+-
+- Called:
+- eraC2ixys celestial-to-intermediate matrix, given X,Y and s
+- eraS00 the CIO locator s, given X,Y, IAU 2000A
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2ixy(date1, date2, x, y)
+- return rc2i
+-
+-
+-def c2ixys(x, y, s):
+- """
+- Wrapper for ERFA function ``eraC2ixys``.
+-
+- Parameters
+- ----------
+- x : double array
+- y : double array
+- s : double array
+-
+- Returns
+- -------
+- rc2i : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 i x y s
+- - - - - - - - - - -
+-
+- Form the celestial to intermediate-frame-of-date matrix given the CIP
+- X,Y and the CIO locator s.
+-
+- Given:
+- x,y double Celestial Intermediate Pole (Note 1)
+- s double the CIO locator s (Note 2)
+-
+- Returned:
+- rc2i double[3][3] celestial-to-intermediate matrix (Note 3)
+-
+- Notes:
+-
+- 1) The Celestial Intermediate Pole coordinates are the x,y
+- components of the unit vector in the Geocentric Celestial
+- Reference System.
+-
+- 2) The CIO locator s (in radians) positions the Celestial
+- Intermediate Origin on the equator of the CIP.
+-
+- 3) The matrix rc2i is the first stage in the transformation from
+- celestial to terrestrial coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = RC2T * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- Called:
+- eraIr initialize r-matrix to identity
+- eraRz rotate around Z-axis
+- eraRy rotate around Y-axis
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2i = ufunc.c2ixys(x, y, s)
+- return rc2i
+-
+-
+-def c2t00a(tta, ttb, uta, utb, xp, yp):
+- """
+- Wrapper for ERFA function ``eraC2t00a``.
+-
+- Parameters
+- ----------
+- tta : double array
+- ttb : double array
+- uta : double array
+- utb : double array
+- xp : double array
+- yp : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 t 0 0 a
+- - - - - - - - - - -
+-
+- Form the celestial to terrestrial matrix given the date, the UT1 and
+- the polar motion, using the IAU 2000A nutation model.
+-
+- Given:
+- tta,ttb double TT as a 2-part Julian Date (Note 1)
+- uta,utb double UT1 as a 2-part Julian Date (Note 1)
+- xp,yp double coordinates of the pole (radians, Note 2)
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 3)
+-
+- Notes:
+-
+- 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates,
+- apportioned in any convenient way between the arguments uta and
+- utb. For example, JD(UT1)=2450123.7 could be expressed in any of
+- these ways, among others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. In the case of uta,utb, the
+- date & time method is best matched to the Earth rotation angle
+- algorithm used: maximum precision is delivered when the uta
+- argument is for 0hrs UT1 on the day in question and the utb
+- argument lies in the range 0 to 1, or vice versa.
+-
+- 2) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 3) The matrix rc2t transforms from celestial to terrestrial
+- coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * RC2I * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), RC2I is the
+- celestial-to-intermediate matrix, ERA is the Earth rotation
+- angle and RPOM is the polar motion matrix.
+-
+- 4) A faster, but slightly less accurate result (about 1 mas), can
+- be obtained by using instead the eraC2t00b function.
+-
+- Called:
+- eraC2i00a celestial-to-intermediate matrix, IAU 2000A
+- eraEra00 Earth rotation angle, IAU 2000
+- eraSp00 the TIO locator s', IERS 2000
+- eraPom00 polar motion matrix
+- eraC2tcio form CIO-based celestial-to-terrestrial matrix
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2t00a(tta, ttb, uta, utb, xp, yp)
+- return rc2t
+-
+-
+-def c2t00b(tta, ttb, uta, utb, xp, yp):
+- """
+- Wrapper for ERFA function ``eraC2t00b``.
+-
+- Parameters
+- ----------
+- tta : double array
+- ttb : double array
+- uta : double array
+- utb : double array
+- xp : double array
+- yp : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 t 0 0 b
+- - - - - - - - - - -
+-
+- Form the celestial to terrestrial matrix given the date, the UT1 and
+- the polar motion, using the IAU 2000B nutation model.
+-
+- Given:
+- tta,ttb double TT as a 2-part Julian Date (Note 1)
+- uta,utb double UT1 as a 2-part Julian Date (Note 1)
+- xp,yp double coordinates of the pole (radians, Note 2)
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 3)
+-
+- Notes:
+-
+- 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates,
+- apportioned in any convenient way between the arguments uta and
+- utb. For example, JD(UT1)=2450123.7 could be expressed in any of
+- these ways, among others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. In the case of uta,utb, the
+- date & time method is best matched to the Earth rotation angle
+- algorithm used: maximum precision is delivered when the uta
+- argument is for 0hrs UT1 on the day in question and the utb
+- argument lies in the range 0 to 1, or vice versa.
+-
+- 2) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 3) The matrix rc2t transforms from celestial to terrestrial
+- coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * RC2I * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), RC2I is the
+- celestial-to-intermediate matrix, ERA is the Earth rotation
+- angle and RPOM is the polar motion matrix.
+-
+- 4) The present function is faster, but slightly less accurate (about
+- 1 mas), than the eraC2t00a function.
+-
+- Called:
+- eraC2i00b celestial-to-intermediate matrix, IAU 2000B
+- eraEra00 Earth rotation angle, IAU 2000
+- eraPom00 polar motion matrix
+- eraC2tcio form CIO-based celestial-to-terrestrial matrix
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2t00b(tta, ttb, uta, utb, xp, yp)
+- return rc2t
+-
+-
+-def c2t06a(tta, ttb, uta, utb, xp, yp):
+- """
+- Wrapper for ERFA function ``eraC2t06a``.
+-
+- Parameters
+- ----------
+- tta : double array
+- ttb : double array
+- uta : double array
+- utb : double array
+- xp : double array
+- yp : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 t 0 6 a
+- - - - - - - - - - -
+-
+- Form the celestial to terrestrial matrix given the date, the UT1 and
+- the polar motion, using the IAU 2006 precession and IAU 2000A
+- nutation models.
+-
+- Given:
+- tta,ttb double TT as a 2-part Julian Date (Note 1)
+- uta,utb double UT1 as a 2-part Julian Date (Note 1)
+- xp,yp double coordinates of the pole (radians, Note 2)
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 3)
+-
+- Notes:
+-
+- 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates,
+- apportioned in any convenient way between the arguments uta and
+- utb. For example, JD(UT1)=2450123.7 could be expressed in any of
+- these ways, among others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. In the case of uta,utb, the
+- date & time method is best matched to the Earth rotation angle
+- algorithm used: maximum precision is delivered when the uta
+- argument is for 0hrs UT1 on the day in question and the utb
+- argument lies in the range 0 to 1, or vice versa.
+-
+- 2) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 3) The matrix rc2t transforms from celestial to terrestrial
+- coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * RC2I * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), RC2I is the
+- celestial-to-intermediate matrix, ERA is the Earth rotation
+- angle and RPOM is the polar motion matrix.
+-
+- Called:
+- eraC2i06a celestial-to-intermediate matrix, IAU 2006/2000A
+- eraEra00 Earth rotation angle, IAU 2000
+- eraSp00 the TIO locator s', IERS 2000
+- eraPom00 polar motion matrix
+- eraC2tcio form CIO-based celestial-to-terrestrial matrix
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2t06a(tta, ttb, uta, utb, xp, yp)
+- return rc2t
+-
+-
+-def c2tcio(rc2i, era, rpom):
+- """
+- Wrapper for ERFA function ``eraC2tcio``.
+-
+- Parameters
+- ----------
+- rc2i : double array
+- era : double array
+- rpom : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 t c i o
+- - - - - - - - - - -
+-
+- Assemble the celestial to terrestrial matrix from CIO-based
+- components (the celestial-to-intermediate matrix, the Earth Rotation
+- Angle and the polar motion matrix).
+-
+- Given:
+- rc2i double[3][3] celestial-to-intermediate matrix
+- era double Earth rotation angle (radians)
+- rpom double[3][3] polar-motion matrix
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix
+-
+- Notes:
+-
+- 1) This function constructs the rotation matrix that transforms
+- vectors in the celestial system into vectors in the terrestrial
+- system. It does so starting from precomputed components, namely
+- the matrix which rotates from celestial coordinates to the
+- intermediate frame, the Earth rotation angle and the polar motion
+- matrix. One use of the present function is when generating a
+- series of celestial-to-terrestrial matrices where only the Earth
+- Rotation Angle changes, avoiding the considerable overhead of
+- recomputing the precession-nutation more often than necessary to
+- achieve given accuracy objectives.
+-
+- 2) The relationship between the arguments is as follows:
+-
+- [TRS] = RPOM * R_3(ERA) * rc2i * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003).
+-
+- Called:
+- eraCr copy r-matrix
+- eraRz rotate around Z-axis
+- eraRxr product of two r-matrices
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2tcio(rc2i, era, rpom)
+- return rc2t
+-
+-
+-def c2teqx(rbpn, gst, rpom):
+- """
+- Wrapper for ERFA function ``eraC2teqx``.
+-
+- Parameters
+- ----------
+- rbpn : double array
+- gst : double array
+- rpom : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a C 2 t e q x
+- - - - - - - - - - -
+-
+- Assemble the celestial to terrestrial matrix from equinox-based
+- components (the celestial-to-true matrix, the Greenwich Apparent
+- Sidereal Time and the polar motion matrix).
+-
+- Given:
+- rbpn double[3][3] celestial-to-true matrix
+- gst double Greenwich (apparent) Sidereal Time (radians)
+- rpom double[3][3] polar-motion matrix
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 2)
+-
+- Notes:
+-
+- 1) This function constructs the rotation matrix that transforms
+- vectors in the celestial system into vectors in the terrestrial
+- system. It does so starting from precomputed components, namely
+- the matrix which rotates from celestial coordinates to the
+- true equator and equinox of date, the Greenwich Apparent Sidereal
+- Time and the polar motion matrix. One use of the present function
+- is when generating a series of celestial-to-terrestrial matrices
+- where only the Sidereal Time changes, avoiding the considerable
+- overhead of recomputing the precession-nutation more often than
+- necessary to achieve given accuracy objectives.
+-
+- 2) The relationship between the arguments is as follows:
+-
+- [TRS] = rpom * R_3(gst) * rbpn * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003).
+-
+- Called:
+- eraCr copy r-matrix
+- eraRz rotate around Z-axis
+- eraRxr product of two r-matrices
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2teqx(rbpn, gst, rpom)
+- return rc2t
+-
+-
+-def c2tpe(tta, ttb, uta, utb, dpsi, deps, xp, yp):
+- """
+- Wrapper for ERFA function ``eraC2tpe``.
+-
+- Parameters
+- ----------
+- tta : double array
+- ttb : double array
+- uta : double array
+- utb : double array
+- dpsi : double array
+- deps : double array
+- xp : double array
+- yp : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a C 2 t p e
+- - - - - - - - - -
+-
+- Form the celestial to terrestrial matrix given the date, the UT1,
+- the nutation and the polar motion. IAU 2000.
+-
+- Given:
+- tta,ttb double TT as a 2-part Julian Date (Note 1)
+- uta,utb double UT1 as a 2-part Julian Date (Note 1)
+- dpsi,deps double nutation (Note 2)
+- xp,yp double coordinates of the pole (radians, Note 3)
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 4)
+-
+- Notes:
+-
+- 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates,
+- apportioned in any convenient way between the arguments uta and
+- utb. For example, JD(UT1)=2450123.7 could be expressed in any of
+- these ways, among others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. In the case of uta,utb, the
+- date & time method is best matched to the Earth rotation angle
+- algorithm used: maximum precision is delivered when the uta
+- argument is for 0hrs UT1 on the day in question and the utb
+- argument lies in the range 0 to 1, or vice versa.
+-
+- 2) The caller is responsible for providing the nutation components;
+- they are in longitude and obliquity, in radians and are with
+- respect to the equinox and ecliptic of date. For high-accuracy
+- applications, free core nutation should be included as well as
+- any other relevant corrections to the position of the CIP.
+-
+- 3) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 4) The matrix rc2t transforms from celestial to terrestrial
+- coordinates:
+-
+- [TRS] = RPOM * R_3(GST) * RBPN * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), RBPN is the
+- bias-precession-nutation matrix, GST is the Greenwich (apparent)
+- Sidereal Time and RPOM is the polar motion matrix.
+-
+- 5) Although its name does not include "00", This function is in fact
+- specific to the IAU 2000 models.
+-
+- Called:
+- eraPn00 bias/precession/nutation results, IAU 2000
+- eraGmst00 Greenwich mean sidereal time, IAU 2000
+- eraSp00 the TIO locator s', IERS 2000
+- eraEe00 equation of the equinoxes, IAU 2000
+- eraPom00 polar motion matrix
+- eraC2teqx form equinox-based celestial-to-terrestrial matrix
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2tpe(tta, ttb, uta, utb, dpsi, deps, xp, yp)
+- return rc2t
+-
+-
+-def c2txy(tta, ttb, uta, utb, x, y, xp, yp):
+- """
+- Wrapper for ERFA function ``eraC2txy``.
+-
+- Parameters
+- ----------
+- tta : double array
+- ttb : double array
+- uta : double array
+- utb : double array
+- x : double array
+- y : double array
+- xp : double array
+- yp : double array
+-
+- Returns
+- -------
+- rc2t : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a C 2 t x y
+- - - - - - - - - -
+-
+- Form the celestial to terrestrial matrix given the date, the UT1,
+- the CIP coordinates and the polar motion. IAU 2000.
+-
+- Given:
+- tta,ttb double TT as a 2-part Julian Date (Note 1)
+- uta,utb double UT1 as a 2-part Julian Date (Note 1)
+- x,y double Celestial Intermediate Pole (Note 2)
+- xp,yp double coordinates of the pole (radians, Note 3)
+-
+- Returned:
+- rc2t double[3][3] celestial-to-terrestrial matrix (Note 4)
+-
+- Notes:
+-
+- 1) The TT and UT1 dates tta+ttb and uta+utb are Julian Dates,
+- apportioned in any convenient way between the arguments uta and
+- utb. For example, JD(UT1)=2450123.7 could be expressed in any o
+- these ways, among others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. In the case of uta,utb, the
+- date & time method is best matched to the Earth rotation angle
+- algorithm used: maximum precision is delivered when the uta
+- argument is for 0hrs UT1 on the day in question and the utb
+- argument lies in the range 0 to 1, or vice versa.
+-
+- 2) The Celestial Intermediate Pole coordinates are the x,y
+- components of the unit vector in the Geocentric Celestial
+- Reference System.
+-
+- 3) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 4) The matrix rc2t transforms from celestial to terrestrial
+- coordinates:
+-
+- [TRS] = RPOM * R_3(ERA) * RC2I * [CRS]
+-
+- = rc2t * [CRS]
+-
+- where [CRS] is a vector in the Geocentric Celestial Reference
+- System and [TRS] is a vector in the International Terrestrial
+- Reference System (see IERS Conventions 2003), ERA is the Earth
+- Rotation Angle and RPOM is the polar motion matrix.
+-
+- 5) Although its name does not include "00", This function is in fact
+- specific to the IAU 2000 models.
+-
+- Called:
+- eraC2ixy celestial-to-intermediate matrix, given X,Y
+- eraEra00 Earth rotation angle, IAU 2000
+- eraSp00 the TIO locator s', IERS 2000
+- eraPom00 polar motion matrix
+- eraC2tcio form CIO-based celestial-to-terrestrial matrix
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rc2t = ufunc.c2txy(tta, ttb, uta, utb, x, y, xp, yp)
+- return rc2t
+-
+-
+-def eo06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEo06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E o 0 6 a
+- - - - - - - - - -
+-
+- Equation of the origins, IAU 2006 precession and IAU 2000A nutation.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double equation of the origins in radians
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The equation of the origins is the distance between the true
+- equinox and the celestial intermediate origin and, equivalently,
+- the difference between Earth rotation angle and Greenwich
+- apparent sidereal time (ERA-GST). It comprises the precession
+- (since J2000.0) in right ascension plus the equation of the
+- equinoxes (including the small correction terms).
+-
+- Called:
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+- eraEors equation of the origins, given NPB matrix and s
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.eo06a(date1, date2)
+- return c_retval
+-
+-
+-def eors(rnpb, s):
+- """
+- Wrapper for ERFA function ``eraEors``.
+-
+- Parameters
+- ----------
+- rnpb : double array
+- s : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a E o r s
+- - - - - - - - -
+-
+- Equation of the origins, given the classical NPB matrix and the
+- quantity s.
+-
+- Given:
+- rnpb double[3][3] classical nutation x precession x bias matrix
+- s double the quantity s (the CIO locator)
+-
+- Returned (function value):
+- double the equation of the origins in radians.
+-
+- Notes:
+-
+- 1) The equation of the origins is the distance between the true
+- equinox and the celestial intermediate origin and, equivalently,
+- the difference between Earth rotation angle and Greenwich
+- apparent sidereal time (ERA-GST). It comprises the precession
+- (since J2000.0) in right ascension plus the equation of the
+- equinoxes (including the small correction terms).
+-
+- 2) The algorithm is from Wallace & Capitaine (2006).
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.eors(rnpb, s)
+- return c_retval
+-
+-
+-def fw2m(gamb, phib, psi, eps):
+- """
+- Wrapper for ERFA function ``eraFw2m``.
+-
+- Parameters
+- ----------
+- gamb : double array
+- phib : double array
+- psi : double array
+- eps : double array
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a F w 2 m
+- - - - - - - - -
+-
+- Form rotation matrix given the Fukushima-Williams angles.
+-
+- Given:
+- gamb double F-W angle gamma_bar (radians)
+- phib double F-W angle phi_bar (radians)
+- psi double F-W angle psi (radians)
+- eps double F-W angle epsilon (radians)
+-
+- Returned:
+- r double[3][3] rotation matrix
+-
+- Notes:
+-
+- 1) Naming the following points:
+-
+- e = J2000.0 ecliptic pole,
+- p = GCRS pole,
+- E = ecliptic pole of date,
+- and P = CIP,
+-
+- the four Fukushima-Williams angles are as follows:
+-
+- gamb = gamma = epE
+- phib = phi = pE
+- psi = psi = pEP
+- eps = epsilon = EP
+-
+- 2) The matrix representing the combined effects of frame bias,
+- precession and nutation is:
+-
+- NxPxB = R_1(-eps).R_3(-psi).R_1(phib).R_3(gamb)
+-
+- 3) Three different matrices can be constructed, depending on the
+- supplied angles:
+-
+- o To obtain the nutation x precession x frame bias matrix,
+- generate the four precession angles, generate the nutation
+- components and add them to the psi_bar and epsilon_A angles,
+- and call the present function.
+-
+- o To obtain the precession x frame bias matrix, generate the
+- four precession angles and call the present function.
+-
+- o To obtain the frame bias matrix, generate the four precession
+- angles for date J2000.0 and call the present function.
+-
+- The nutation-only and precession-only matrices can if necessary
+- be obtained by combining these three appropriately.
+-
+- Called:
+- eraIr initialize r-matrix to identity
+- eraRz rotate around Z-axis
+- eraRx rotate around X-axis
+-
+- Reference:
+-
+- Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.fw2m(gamb, phib, psi, eps)
+- return r
+-
+-
+-def fw2xy(gamb, phib, psi, eps):
+- """
+- Wrapper for ERFA function ``eraFw2xy``.
+-
+- Parameters
+- ----------
+- gamb : double array
+- phib : double array
+- psi : double array
+- eps : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F w 2 x y
+- - - - - - - - - -
+-
+- CIP X,Y given Fukushima-Williams bias-precession-nutation angles.
+-
+- Given:
+- gamb double F-W angle gamma_bar (radians)
+- phib double F-W angle phi_bar (radians)
+- psi double F-W angle psi (radians)
+- eps double F-W angle epsilon (radians)
+-
+- Returned:
+- x,y double CIP unit vector X,Y
+-
+- Notes:
+-
+- 1) Naming the following points:
+-
+- e = J2000.0 ecliptic pole,
+- p = GCRS pole
+- E = ecliptic pole of date,
+- and P = CIP,
+-
+- the four Fukushima-Williams angles are as follows:
+-
+- gamb = gamma = epE
+- phib = phi = pE
+- psi = psi = pEP
+- eps = epsilon = EP
+-
+- 2) The matrix representing the combined effects of frame bias,
+- precession and nutation is:
+-
+- NxPxB = R_1(-epsA).R_3(-psi).R_1(phib).R_3(gamb)
+-
+- The returned values x,y are elements [2][0] and [2][1] of the
+- matrix. Near J2000.0, they are essentially angles in radians.
+-
+- Called:
+- eraFw2m F-W angles to r-matrix
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+-
+- Reference:
+-
+- Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y = ufunc.fw2xy(gamb, phib, psi, eps)
+- return x, y
+-
+-
+-def ltp(epj):
+- """
+- Wrapper for ERFA function ``eraLtp``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- rp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a L t p
+- - - - - - - -
+-
+- Long-term precession matrix.
+-
+- Given:
+- epj double Julian epoch (TT)
+-
+- Returned:
+- rp double[3][3] precession matrix, J2000.0 to date
+-
+- Notes:
+-
+- 1) The matrix is in the sense
+-
+- P_date = rp x P_J2000,
+-
+- where P_J2000 is a vector with respect to the J2000.0 mean
+- equator and equinox and P_date is the same vector with respect to
+- the equator and equinox of epoch epj.
+-
+- 2) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- Called:
+- eraLtpequ equator pole, long term
+- eraLtpecl ecliptic pole, long term
+- eraPxp vector product
+- eraPn normalize vector
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rp = ufunc.ltp(epj)
+- return rp
+-
+-
+-def ltpb(epj):
+- """
+- Wrapper for ERFA function ``eraLtpb``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- rpb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a L t p b
+- - - - - - - - -
+-
+- Long-term precession matrix, including ICRS frame bias.
+-
+- Given:
+- epj double Julian epoch (TT)
+-
+- Returned:
+- rpb double[3][3] precession-bias matrix, J2000.0 to date
+-
+- Notes:
+-
+- 1) The matrix is in the sense
+-
+- P_date = rpb x P_ICRS,
+-
+- where P_ICRS is a vector in the Geocentric Celestial Reference
+- System, and P_date is the vector with respect to the Celestial
+- Intermediate Reference System at that date but with nutation
+- neglected.
+-
+- 2) A first order frame bias formulation is used, of sub-
+- microarcsecond accuracy compared with a full 3D rotation.
+-
+- 3) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rpb = ufunc.ltpb(epj)
+- return rpb
+-
+-
+-def ltpecl(epj):
+- """
+- Wrapper for ERFA function ``eraLtpecl``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- vec : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a L t p e c l
+- - - - - - - - - - -
+-
+- Long-term precession of the ecliptic.
+-
+- Given:
+- epj double Julian epoch (TT)
+-
+- Returned:
+- vec double[3] ecliptic pole unit vector
+-
+- Notes:
+-
+- 1) The returned vector is with respect to the J2000.0 mean equator
+- and equinox.
+-
+- 2) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- vec = ufunc.ltpecl(epj)
+- return vec
+-
+-
+-def ltpequ(epj):
+- """
+- Wrapper for ERFA function ``eraLtpequ``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- veq : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a L t p e q u
+- - - - - - - - - - -
+-
+- Long-term precession of the equator.
+-
+- Given:
+- epj double Julian epoch (TT)
+-
+- Returned:
+- veq double[3] equator pole unit vector
+-
+- Notes:
+-
+- 1) The returned vector is with respect to the J2000.0 mean equator
+- and equinox.
+-
+- 2) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- veq = ufunc.ltpequ(epj)
+- return veq
+-
+-
+-def num00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNum00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u m 0 0 a
+- - - - - - - - - - -
+-
+- Form the matrix of nutation for a given date, IAU 2000A model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rmatn double[3][3] nutation matrix
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(true) = rmatn * V(mean), where
+- the p-vector V(true) is with respect to the true equatorial triad
+- of date and the p-vector V(mean) is with respect to the mean
+- equatorial triad of date.
+-
+- 3) A faster, but slightly less accurate result (about 1 mas), can be
+- obtained by using instead the eraNum00b function.
+-
+- Called:
+- eraPn00a bias/precession/nutation, IAU 2000A
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.222-3 (p114).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatn = ufunc.num00a(date1, date2)
+- return rmatn
+-
+-
+-def num00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNum00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u m 0 0 b
+- - - - - - - - - - -
+-
+- Form the matrix of nutation for a given date, IAU 2000B model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rmatn double[3][3] nutation matrix
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(true) = rmatn * V(mean), where
+- the p-vector V(true) is with respect to the true equatorial triad
+- of date and the p-vector V(mean) is with respect to the mean
+- equatorial triad of date.
+-
+- 3) The present function is faster, but slightly less accurate (about
+- 1 mas), than the eraNum00a function.
+-
+- Called:
+- eraPn00b bias/precession/nutation, IAU 2000B
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.222-3 (p114).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatn = ufunc.num00b(date1, date2)
+- return rmatn
+-
+-
+-def num06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNum06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u m 0 6 a
+- - - - - - - - - - -
+-
+- Form the matrix of nutation for a given date, IAU 2006/2000A model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rmatn double[3][3] nutation matrix
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(true) = rmatn * V(mean), where
+- the p-vector V(true) is with respect to the true equatorial triad
+- of date and the p-vector V(mean) is with respect to the mean
+- equatorial triad of date.
+-
+- Called:
+- eraObl06 mean obliquity, IAU 2006
+- eraNut06a nutation, IAU 2006/2000A
+- eraNumat form nutation matrix
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.222-3 (p114).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatn = ufunc.num06a(date1, date2)
+- return rmatn
+-
+-
+-def numat(epsa, dpsi, deps):
+- """
+- Wrapper for ERFA function ``eraNumat``.
+-
+- Parameters
+- ----------
+- epsa : double array
+- dpsi : double array
+- deps : double array
+-
+- Returns
+- -------
+- rmatn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a N u m a t
+- - - - - - - - - -
+-
+- Form the matrix of nutation.
+-
+- Given:
+- epsa double mean obliquity of date (Note 1)
+- dpsi,deps double nutation (Note 2)
+-
+- Returned:
+- rmatn double[3][3] nutation matrix (Note 3)
+-
+- Notes:
+-
+-
+- 1) The supplied mean obliquity epsa, must be consistent with the
+- precession-nutation models from which dpsi and deps were obtained.
+-
+- 2) The caller is responsible for providing the nutation components;
+- they are in longitude and obliquity, in radians and are with
+- respect to the equinox and ecliptic of date.
+-
+- 3) The matrix operates in the sense V(true) = rmatn * V(mean),
+- where the p-vector V(true) is with respect to the true
+- equatorial triad of date and the p-vector V(mean) is with
+- respect to the mean equatorial triad of date.
+-
+- Called:
+- eraIr initialize r-matrix to identity
+- eraRx rotate around X-axis
+- eraRz rotate around Z-axis
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.222-3 (p114).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatn = ufunc.numat(epsa, dpsi, deps)
+- return rmatn
+-
+-
+-def nut00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNut00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u t 0 0 a
+- - - - - - - - - - -
+-
+- Nutation, IAU 2000A model (MHB2000 luni-solar and planetary nutation
+- with free core nutation omitted).
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation, luni-solar + planetary (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components in longitude and obliquity are in radians
+- and with respect to the equinox and ecliptic of date. The
+- obliquity at J2000.0 is assumed to be the Lieske et al. (1977)
+- value of 84381.448 arcsec.
+-
+- Both the luni-solar and planetary nutations are included. The
+- latter are due to direct planetary nutations and the
+- perturbations of the lunar and terrestrial orbits.
+-
+- 3) The function computes the MHB2000 nutation series with the
+- associated corrections for planetary nutations. It is an
+- implementation of the nutation part of the IAU 2000A precession-
+- nutation model, formally adopted by the IAU General Assembly in
+- 2000, namely MHB2000 (Mathews et al. 2002), but with the free
+- core nutation (FCN - see Note 4) omitted.
+-
+- 4) The full MHB2000 model also contains contributions to the
+- nutations in longitude and obliquity due to the free-excitation
+- of the free-core-nutation during the period 1979-2000. These FCN
+- terms, which are time-dependent and unpredictable, are NOT
+- included in the present function and, if required, must be
+- independently computed. With the FCN corrections included, the
+- present function delivers a pole which is at current epochs
+- accurate to a few hundred microarcseconds. The omission of FCN
+- introduces further errors of about that size.
+-
+- 5) The present function provides classical nutation. The MHB2000
+- algorithm, from which it is adapted, deals also with (i) the
+- offsets between the GCRS and mean poles and (ii) the adjustments
+- in longitude and obliquity due to the changed precession rates.
+- These additional functions, namely frame bias and precession
+- adjustments, are supported by the ERFA functions eraBi00 and
+- eraPr00.
+-
+- 6) The MHB2000 algorithm also provides "total" nutations, comprising
+- the arithmetic sum of the frame bias, precession adjustments,
+- luni-solar nutation and planetary nutation. These total
+- nutations can be used in combination with an existing IAU 1976
+- precession implementation, such as eraPmat76, to deliver GCRS-
+- to-true predictions of sub-mas accuracy at current dates.
+- However, there are three shortcomings in the MHB2000 model that
+- must be taken into account if more accurate or definitive results
+- are required (see Wallace 2002):
+-
+- (i) The MHB2000 total nutations are simply arithmetic sums,
+- yet in reality the various components are successive Euler
+- rotations. This slight lack of rigor leads to cross terms
+- that exceed 1 mas after a century. The rigorous procedure
+- is to form the GCRS-to-true rotation matrix by applying the
+- bias, precession and nutation in that order.
+-
+- (ii) Although the precession adjustments are stated to be with
+- respect to Lieske et al. (1977), the MHB2000 model does
+- not specify which set of Euler angles are to be used and
+- how the adjustments are to be applied. The most literal
+- and straightforward procedure is to adopt the 4-rotation
+- epsilon_0, psi_A, omega_A, xi_A option, and to add DPSIPR
+- to psi_A and DEPSPR to both omega_A and eps_A.
+-
+- (iii) The MHB2000 model predates the determination by Chapront
+- et al. (2002) of a 14.6 mas displacement between the
+- J2000.0 mean equinox and the origin of the ICRS frame. It
+- should, however, be noted that neglecting this displacement
+- when calculating star coordinates does not lead to a
+- 14.6 mas change in right ascension, only a small second-
+- order distortion in the pattern of the precession-nutation
+- effect.
+-
+- For these reasons, the ERFA functions do not generate the "total
+- nutations" directly, though they can of course easily be
+- generated by calling eraBi00, eraPr00 and the present function
+- and adding the results.
+-
+- 7) The MHB2000 model contains 41 instances where the same frequency
+- appears multiple times, of which 38 are duplicates and three are
+- triplicates. To keep the present code close to the original MHB
+- algorithm, this small inefficiency has not been corrected.
+-
+- Called:
+- eraFal03 mean anomaly of the Moon
+- eraFaf03 mean argument of the latitude of the Moon
+- eraFaom03 mean longitude of the Moon's ascending node
+- eraFame03 mean longitude of Mercury
+- eraFave03 mean longitude of Venus
+- eraFae03 mean longitude of Earth
+- eraFama03 mean longitude of Mars
+- eraFaju03 mean longitude of Jupiter
+- eraFasa03 mean longitude of Saturn
+- eraFaur03 mean longitude of Uranus
+- eraFapa03 general accumulated precession in longitude
+-
+- References:
+-
+- Chapront, J., Chapront-Touze, M. & Francou, G. 2002,
+- Astron.Astrophys. 387, 700
+-
+- Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977,
+- Astron.Astrophys. 58, 1-16
+-
+- Mathews, P.M., Herring, T.A., Buffet, B.A. 2002, J.Geophys.Res.
+- 107, B4. The MHB_2000 code itself was obtained on 9th September
+- 2002 from ftp//maia.usno.navy.mil/conv2000/chapter5/IAU2000A.
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Wallace, P.T., "Software for Implementing the IAU 2000
+- Resolutions", in IERS Workshop 5.1 (2002)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps = ufunc.nut00a(date1, date2)
+- return dpsi, deps
+-
+-
+-def nut00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNut00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u t 0 0 b
+- - - - - - - - - - -
+-
+- Nutation, IAU 2000B model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation, luni-solar + planetary (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components in longitude and obliquity are in radians
+- and with respect to the equinox and ecliptic of date. The
+- obliquity at J2000.0 is assumed to be the Lieske et al. (1977)
+- value of 84381.448 arcsec. (The errors that result from using
+- this function with the IAU 2006 value of 84381.406 arcsec can be
+- neglected.)
+-
+- The nutation model consists only of luni-solar terms, but
+- includes also a fixed offset which compensates for certain long-
+- period planetary terms (Note 7).
+-
+- 3) This function is an implementation of the IAU 2000B abridged
+- nutation model formally adopted by the IAU General Assembly in
+- 2000. The function computes the MHB_2000_SHORT luni-solar
+- nutation series (Luzum 2001), but without the associated
+- corrections for the precession rate adjustments and the offset
+- between the GCRS and J2000.0 mean poles.
+-
+- 4) The full IAU 2000A (MHB2000) nutation model contains nearly 1400
+- terms. The IAU 2000B model (McCarthy & Luzum 2003) contains only
+- 77 terms, plus additional simplifications, yet still delivers
+- results of 1 mas accuracy at present epochs. This combination of
+- accuracy and size makes the IAU 2000B abridged nutation model
+- suitable for most practical applications.
+-
+- The function delivers a pole accurate to 1 mas from 1900 to 2100
+- (usually better than 1 mas, very occasionally just outside
+- 1 mas). The full IAU 2000A model, which is implemented in the
+- function eraNut00a (q.v.), delivers considerably greater accuracy
+- at current dates; however, to realize this improved accuracy,
+- corrections for the essentially unpredictable free-core-nutation
+- (FCN) must also be included.
+-
+- 5) The present function provides classical nutation. The
+- MHB_2000_SHORT algorithm, from which it is adapted, deals also
+- with (i) the offsets between the GCRS and mean poles and (ii) the
+- adjustments in longitude and obliquity due to the changed
+- precession rates. These additional functions, namely frame bias
+- and precession adjustments, are supported by the ERFA functions
+- eraBi00 and eraPr00.
+-
+- 6) The MHB_2000_SHORT algorithm also provides "total" nutations,
+- comprising the arithmetic sum of the frame bias, precession
+- adjustments, and nutation (luni-solar + planetary). These total
+- nutations can be used in combination with an existing IAU 1976
+- precession implementation, such as eraPmat76, to deliver GCRS-
+- to-true predictions of mas accuracy at current epochs. However,
+- for symmetry with the eraNut00a function (q.v. for the reasons),
+- the ERFA functions do not generate the "total nutations"
+- directly. Should they be required, they could of course easily
+- be generated by calling eraBi00, eraPr00 and the present function
+- and adding the results.
+-
+- 7) The IAU 2000B model includes "planetary bias" terms that are
+- fixed in size but compensate for long-period nutations. The
+- amplitudes quoted in McCarthy & Luzum (2003), namely
+- Dpsi = -1.5835 mas and Depsilon = +1.6339 mas, are optimized for
+- the "total nutations" method described in Note 6. The Luzum
+- (2001) values used in this ERFA implementation, namely -0.135 mas
+- and +0.388 mas, are optimized for the "rigorous" method, where
+- frame bias, precession and nutation are applied separately and in
+- that order. During the interval 1995-2050, the ERFA
+- implementation delivers a maximum error of 1.001 mas (not
+- including FCN).
+-
+- References:
+-
+- Lieske, J.H., Lederle, T., Fricke, W., Morando, B., "Expressions
+- for the precession quantities based upon the IAU /1976/ system of
+- astronomical constants", Astron.Astrophys. 58, 1-2, 1-16. (1977)
+-
+- Luzum, B., private communication, 2001 (Fortran code
+- MHB_2000_SHORT)
+-
+- McCarthy, D.D. & Luzum, B.J., "An abridged model of the
+- precession-nutation of the celestial pole", Cel.Mech.Dyn.Astron.
+- 85, 37-49 (2003)
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J., Astron.Astrophys. 282, 663-683 (1994)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps = ufunc.nut00b(date1, date2)
+- return dpsi, deps
+-
+-
+-def nut06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNut06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u t 0 6 a
+- - - - - - - - - - -
+-
+- IAU 2000A nutation with adjustments to match the IAU 2006
+- precession.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation, luni-solar + planetary (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components in longitude and obliquity are in radians
+- and with respect to the mean equinox and ecliptic of date,
+- IAU 2006 precession model (Hilton et al. 2006, Capitaine et al.
+- 2005).
+-
+- 3) The function first computes the IAU 2000A nutation, then applies
+- adjustments for (i) the consequences of the change in obliquity
+- from the IAU 1980 ecliptic to the IAU 2006 ecliptic and (ii) the
+- secular variation in the Earth's dynamical form factor J2.
+-
+- 4) The present function provides classical nutation, complementing
+- the IAU 2000 frame bias and IAU 2006 precession. It delivers a
+- pole which is at current epochs accurate to a few tens of
+- microarcseconds, apart from the free core nutation.
+-
+- Called:
+- eraNut00a nutation, IAU 2000A
+-
+- References:
+-
+- Chapront, J., Chapront-Touze, M. & Francou, G. 2002,
+- Astron.Astrophys. 387, 700
+-
+- Lieske, J.H., Lederle, T., Fricke, W. & Morando, B. 1977,
+- Astron.Astrophys. 58, 1-16
+-
+- Mathews, P.M., Herring, T.A., Buffet, B.A. 2002, J.Geophys.Res.
+- 107, B4. The MHB_2000 code itself was obtained on 9th September
+- 2002 from ftp//maia.usno.navy.mil/conv2000/chapter5/IAU2000A.
+-
+- Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G., Laskar, J. 1994, Astron.Astrophys. 282, 663-683
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M. 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Wallace, P.T., "Software for Implementing the IAU 2000
+- Resolutions", in IERS Workshop 5.1 (2002)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps = ufunc.nut06a(date1, date2)
+- return dpsi, deps
+-
+-
+-def nut80(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNut80``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a N u t 8 0
+- - - - - - - - - -
+-
+- Nutation, IAU 1980 model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi double nutation in longitude (radians)
+- deps double nutation in obliquity (radians)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components are with respect to the ecliptic of
+- date.
+-
+- Called:
+- eraAnpm normalize angle into range +/- pi
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.222 (p111).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps = ufunc.nut80(date1, date2)
+- return dpsi, deps
+-
+-
+-def nutm80(date1, date2):
+- """
+- Wrapper for ERFA function ``eraNutm80``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a N u t m 8 0
+- - - - - - - - - - -
+-
+- Form the matrix of nutation for a given date, IAU 1980 model.
+-
+- Given:
+- date1,date2 double TDB date (Note 1)
+-
+- Returned:
+- rmatn double[3][3] nutation matrix
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(true) = rmatn * V(mean),
+- where the p-vector V(true) is with respect to the true
+- equatorial triad of date and the p-vector V(mean) is with
+- respect to the mean equatorial triad of date.
+-
+- Called:
+- eraNut80 nutation, IAU 1980
+- eraObl80 mean obliquity, IAU 1980
+- eraNumat form nutation matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatn = ufunc.nutm80(date1, date2)
+- return rmatn
+-
+-
+-def obl06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraObl06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a O b l 0 6
+- - - - - - - - - -
+-
+- Mean obliquity of the ecliptic, IAU 2006 precession model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double obliquity of the ecliptic (radians, Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result is the angle between the ecliptic and mean equator of
+- date date1+date2.
+-
+- Reference:
+-
+- Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.obl06(date1, date2)
+- return c_retval
+-
+-
+-def obl80(date1, date2):
+- """
+- Wrapper for ERFA function ``eraObl80``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a O b l 8 0
+- - - - - - - - - -
+-
+- Mean obliquity of the ecliptic, IAU 1980 model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double obliquity of the ecliptic (radians, Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result is the angle between the ecliptic and mean equator of
+- date date1+date2.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Expression 3.222-1 (p114).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.obl80(date1, date2)
+- return c_retval
+-
+-
+-def p06e(date1, date2):
+- """
+- Wrapper for ERFA function ``eraP06e``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- eps0 : double array
+- psia : double array
+- oma : double array
+- bpa : double array
+- bqa : double array
+- pia : double array
+- bpia : double array
+- epsa : double array
+- chia : double array
+- za : double array
+- zetaa : double array
+- thetaa : double array
+- pa : double array
+- gam : double array
+- phi : double array
+- psi : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P 0 6 e
+- - - - - - - - -
+-
+- Precession angles, IAU 2006, equinox based.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (see Note 2):
+- eps0 double epsilon_0
+- psia double psi_A
+- oma double omega_A
+- bpa double P_A
+- bqa double Q_A
+- pia double pi_A
+- bpia double Pi_A
+- epsa double obliquity epsilon_A
+- chia double chi_A
+- za double z_A
+- zetaa double zeta_A
+- thetaa double theta_A
+- pa double p_A
+- gam double F-W angle gamma_J2000
+- phi double F-W angle phi_J2000
+- psi double F-W angle psi_J2000
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) This function returns the set of equinox based angles for the
+- Capitaine et al. "P03" precession theory, adopted by the IAU in
+- 2006. The angles are set out in Table 1 of Hilton et al. (2006):
+-
+- eps0 epsilon_0 obliquity at J2000.0
+- psia psi_A luni-solar precession
+- oma omega_A inclination of equator wrt J2000.0 ecliptic
+- bpa P_A ecliptic pole x, J2000.0 ecliptic triad
+- bqa Q_A ecliptic pole -y, J2000.0 ecliptic triad
+- pia pi_A angle between moving and J2000.0 ecliptics
+- bpia Pi_A longitude of ascending node of the ecliptic
+- epsa epsilon_A obliquity of the ecliptic
+- chia chi_A planetary precession
+- za z_A equatorial precession: -3rd 323 Euler angle
+- zetaa zeta_A equatorial precession: -1st 323 Euler angle
+- thetaa theta_A equatorial precession: 2nd 323 Euler angle
+- pa p_A general precession
+- gam gamma_J2000 J2000.0 RA difference of ecliptic poles
+- phi phi_J2000 J2000.0 codeclination of ecliptic pole
+- psi psi_J2000 longitude difference of equator poles, J2000.0
+-
+- The returned values are all radians.
+-
+- 3) Hilton et al. (2006) Table 1 also contains angles that depend on
+- models distinct from the P03 precession theory itself, namely the
+- IAU 2000A frame bias and nutation. The quoted polynomials are
+- used in other ERFA functions:
+-
+- . eraXy06 contains the polynomial parts of the X and Y series.
+-
+- . eraS06 contains the polynomial part of the s+XY/2 series.
+-
+- . eraPfw06 implements the series for the Fukushima-Williams
+- angles that are with respect to the GCRS pole (i.e. the variants
+- that include frame bias).
+-
+- 4) The IAU resolution stipulated that the choice of parameterization
+- was left to the user, and so an IAU compliant precession
+- implementation can be constructed using various combinations of
+- the angles returned by the present function.
+-
+- 5) The parameterization used by ERFA is the version of the Fukushima-
+- Williams angles that refers directly to the GCRS pole. These
+- angles may be calculated by calling the function eraPfw06. ERFA
+- also supports the direct computation of the CIP GCRS X,Y by
+- series, available by calling eraXy06.
+-
+- 6) The agreement between the different parameterizations is at the
+- 1 microarcsecond level in the present era.
+-
+- 7) When constructing a precession formulation that refers to the GCRS
+- pole rather than the dynamical pole, it may (depending on the
+- choice of angles) be necessary to introduce the frame bias
+- explicitly.
+-
+- 8) It is permissible to re-use the same variable in the returned
+- arguments. The quantities are stored in the stated order.
+-
+- Reference:
+-
+- Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351
+-
+- Called:
+- eraObl06 mean obliquity, IAU 2006
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- eps0, psia, oma, bpa, bqa, pia, bpia, epsa, chia, za, zetaa, thetaa, pa, gam, phi, psi = ufunc.p06e(date1, date2)
+- return eps0, psia, oma, bpa, bqa, pia, bpia, epsa, chia, za, zetaa, thetaa, pa, gam, phi, psi
+-
+-
+-def pb06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPb06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- bzeta : double array
+- bz : double array
+- btheta : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P b 0 6
+- - - - - - - - -
+-
+- This function forms three Euler angles which implement general
+- precession from epoch J2000.0, using the IAU 2006 model. Frame
+- bias (the offset between ICRS and mean J2000.0) is included.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- bzeta double 1st rotation: radians cw around z
+- bz double 3rd rotation: radians cw around z
+- btheta double 2nd rotation: radians ccw around y
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The traditional accumulated precession angles zeta_A, z_A,
+- theta_A cannot be obtained in the usual way, namely through
+- polynomial expressions, because of the frame bias. The latter
+- means that two of the angles undergo rapid changes near this
+- date. They are instead the results of decomposing the
+- precession-bias matrix obtained by using the Fukushima-Williams
+- method, which does not suffer from the problem. The
+- decomposition returns values which can be used in the
+- conventional formulation and which include frame bias.
+-
+- 3) The three angles are returned in the conventional order, which
+- is not the same as the order of the corresponding Euler
+- rotations. The precession-bias matrix is
+- R_3(-z) x R_2(+theta) x R_3(-zeta).
+-
+- 4) Should zeta_A, z_A, theta_A angles be required that do not
+- contain frame bias, they are available by calling the ERFA
+- function eraP06e.
+-
+- Called:
+- eraPmat06 PB matrix, IAU 2006
+- eraRz rotate around Z-axis
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- bzeta, bz, btheta = ufunc.pb06(date1, date2)
+- return bzeta, bz, btheta
+-
+-
+-def pfw06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPfw06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- gamb : double array
+- phib : double array
+- psib : double array
+- epsa : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P f w 0 6
+- - - - - - - - - -
+-
+- Precession angles, IAU 2006 (Fukushima-Williams 4-angle formulation).
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- gamb double F-W angle gamma_bar (radians)
+- phib double F-W angle phi_bar (radians)
+- psib double F-W angle psi_bar (radians)
+- epsa double F-W angle epsilon_A (radians)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) Naming the following points:
+-
+- e = J2000.0 ecliptic pole,
+- p = GCRS pole,
+- E = mean ecliptic pole of date,
+- and P = mean pole of date,
+-
+- the four Fukushima-Williams angles are as follows:
+-
+- gamb = gamma_bar = epE
+- phib = phi_bar = pE
+- psib = psi_bar = pEP
+- epsa = epsilon_A = EP
+-
+- 3) The matrix representing the combined effects of frame bias and
+- precession is:
+-
+- PxB = R_1(-epsa).R_3(-psib).R_1(phib).R_3(gamb)
+-
+- 4) The matrix representing the combined effects of frame bias,
+- precession and nutation is simply:
+-
+- NxPxB = R_1(-epsa-dE).R_3(-psib-dP).R_1(phib).R_3(gamb)
+-
+- where dP and dE are the nutation components with respect to the
+- ecliptic of date.
+-
+- Reference:
+-
+- Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351
+-
+- Called:
+- eraObl06 mean obliquity, IAU 2006
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- gamb, phib, psib, epsa = ufunc.pfw06(date1, date2)
+- return gamb, phib, psib, epsa
+-
+-
+-def pmat00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPmat00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rbp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P m a t 0 0
+- - - - - - - - - - -
+-
+- Precession matrix (including frame bias) from GCRS to a specified
+- date, IAU 2000 model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rbp double[3][3] bias-precession matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rbp * V(GCRS), where
+- the p-vector V(GCRS) is with respect to the Geocentric Celestial
+- Reference System (IAU, 2000) and the p-vector V(date) is with
+- respect to the mean equatorial triad of the given date.
+-
+- Called:
+- eraBp00 frame bias and precession matrices, IAU 2000
+-
+- Reference:
+-
+- IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc.
+- 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6.
+- (2000)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rbp = ufunc.pmat00(date1, date2)
+- return rbp
+-
+-
+-def pmat06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPmat06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rbp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P m a t 0 6
+- - - - - - - - - - -
+-
+- Precession matrix (including frame bias) from GCRS to a specified
+- date, IAU 2006 model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rbp double[3][3] bias-precession matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rbp * V(GCRS), where
+- the p-vector V(GCRS) is with respect to the Geocentric Celestial
+- Reference System (IAU, 2000) and the p-vector V(date) is with
+- respect to the mean equatorial triad of the given date.
+-
+- Called:
+- eraPfw06 bias-precession F-W angles, IAU 2006
+- eraFw2m F-W angles to r-matrix
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rbp = ufunc.pmat06(date1, date2)
+- return rbp
+-
+-
+-def pmat76(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPmat76``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P m a t 7 6
+- - - - - - - - - - -
+-
+- Precession matrix from J2000.0 to a specified date, IAU 1976 model.
+-
+- Given:
+- date1,date2 double ending date, TT (Note 1)
+-
+- Returned:
+- rmatp double[3][3] precession matrix, J2000.0 -> date1+date2
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = RMATP * V(J2000),
+- where the p-vector V(J2000) is with respect to the mean
+- equatorial triad of epoch J2000.0 and the p-vector V(date)
+- is with respect to the mean equatorial triad of the given
+- date.
+-
+- 3) Though the matrix method itself is rigorous, the precession
+- angles are expressed through canonical polynomials which are
+- valid only for a limited time span. In addition, the IAU 1976
+- precession rate is known to be imperfect. The absolute accuracy
+- of the present formulation is better than 0.1 arcsec from
+- 1960AD to 2040AD, better than 1 arcsec from 1640AD to 2360AD,
+- and remains below 3 arcsec for the whole of the period
+- 500BC to 3000AD. The errors exceed 10 arcsec outside the
+- range 1200BC to 3900AD, exceed 100 arcsec outside 4200BC to
+- 5600AD and exceed 1000 arcsec outside 6800BC to 8200AD.
+-
+- Called:
+- eraPrec76 accumulated precession angles, IAU 1976
+- eraIr initialize r-matrix to identity
+- eraRz rotate around Z-axis
+- eraRy rotate around Y-axis
+- eraCr copy r-matrix
+-
+- References:
+-
+- Lieske, J.H., 1979, Astron.Astrophys. 73, 282.
+- equations (6) & (7), p283.
+-
+- Kaplan,G.H., 1981. USNO circular no. 163, pA2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatp = ufunc.pmat76(date1, date2)
+- return rmatp
+-
+-
+-def pn00(date1, date2, dpsi, deps):
+- """
+- Wrapper for ERFA function ``eraPn00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- dpsi : double array
+- deps : double array
+-
+- Returns
+- -------
+- epsa : double array
+- rb : double array
+- rp : double array
+- rbp : double array
+- rn : double array
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P n 0 0
+- - - - - - - - -
+-
+- Precession-nutation, IAU 2000 model: a multi-purpose function,
+- supporting classical (equinox-based) use directly and CIO-based
+- use indirectly.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- dpsi,deps double nutation (Note 2)
+-
+- Returned:
+- epsa double mean obliquity (Note 3)
+- rb double[3][3] frame bias matrix (Note 4)
+- rp double[3][3] precession matrix (Note 5)
+- rbp double[3][3] bias-precession matrix (Note 6)
+- rn double[3][3] nutation matrix (Note 7)
+- rbpn double[3][3] GCRS-to-true matrix (Note 8)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The caller is responsible for providing the nutation components;
+- they are in longitude and obliquity, in radians and are with
+- respect to the equinox and ecliptic of date. For high-accuracy
+- applications, free core nutation should be included as well as
+- any other relevant corrections to the position of the CIP.
+-
+- 3) The returned mean obliquity is consistent with the IAU 2000
+- precession-nutation models.
+-
+- 4) The matrix rb transforms vectors from GCRS to J2000.0 mean
+- equator and equinox by applying frame bias.
+-
+- 5) The matrix rp transforms vectors from J2000.0 mean equator and
+- equinox to mean equator and equinox of date by applying
+- precession.
+-
+- 6) The matrix rbp transforms vectors from GCRS to mean equator and
+- equinox of date by applying frame bias then precession. It is
+- the product rp x rb.
+-
+- 7) The matrix rn transforms vectors from mean equator and equinox of
+- date to true equator and equinox of date by applying the nutation
+- (luni-solar + planetary).
+-
+- 8) The matrix rbpn transforms vectors from GCRS to true equator and
+- equinox of date. It is the product rn x rbp, applying frame
+- bias, precession and nutation in that order.
+-
+- 9) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the order given.
+-
+- Called:
+- eraPr00 IAU 2000 precession adjustments
+- eraObl80 mean obliquity, IAU 1980
+- eraBp00 frame bias and precession matrices, IAU 2000
+- eraCr copy r-matrix
+- eraNumat form nutation matrix
+- eraRxr product of two r-matrices
+-
+- Reference:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- epsa, rb, rp, rbp, rn, rbpn = ufunc.pn00(date1, date2, dpsi, deps)
+- return epsa, rb, rp, rbp, rn, rbpn
+-
+-
+-def pn00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPn00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+- epsa : double array
+- rb : double array
+- rp : double array
+- rbp : double array
+- rn : double array
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P n 0 0 a
+- - - - - - - - - -
+-
+- Precession-nutation, IAU 2000A model: a multi-purpose function,
+- supporting classical (equinox-based) use directly and CIO-based
+- use indirectly.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation (Note 2)
+- epsa double mean obliquity (Note 3)
+- rb double[3][3] frame bias matrix (Note 4)
+- rp double[3][3] precession matrix (Note 5)
+- rbp double[3][3] bias-precession matrix (Note 6)
+- rn double[3][3] nutation matrix (Note 7)
+- rbpn double[3][3] GCRS-to-true matrix (Notes 8,9)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components (luni-solar + planetary, IAU 2000A) in
+- longitude and obliquity are in radians and with respect to the
+- equinox and ecliptic of date. Free core nutation is omitted;
+- for the utmost accuracy, use the eraPn00 function, where the
+- nutation components are caller-specified. For faster but
+- slightly less accurate results, use the eraPn00b function.
+-
+- 3) The mean obliquity is consistent with the IAU 2000 precession.
+-
+- 4) The matrix rb transforms vectors from GCRS to J2000.0 mean
+- equator and equinox by applying frame bias.
+-
+- 5) The matrix rp transforms vectors from J2000.0 mean equator and
+- equinox to mean equator and equinox of date by applying
+- precession.
+-
+- 6) The matrix rbp transforms vectors from GCRS to mean equator and
+- equinox of date by applying frame bias then precession. It is
+- the product rp x rb.
+-
+- 7) The matrix rn transforms vectors from mean equator and equinox
+- of date to true equator and equinox of date by applying the
+- nutation (luni-solar + planetary).
+-
+- 8) The matrix rbpn transforms vectors from GCRS to true equator and
+- equinox of date. It is the product rn x rbp, applying frame
+- bias, precession and nutation in that order.
+-
+- 9) The X,Y,Z coordinates of the IAU 2000A Celestial Intermediate
+- Pole are elements (3,1-3) of the GCRS-to-true matrix,
+- i.e. rbpn[2][0-2].
+-
+- 10) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the order given.
+-
+- Called:
+- eraNut00a nutation, IAU 2000A
+- eraPn00 bias/precession/nutation results, IAU 2000
+-
+- Reference:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps, epsa, rb, rp, rbp, rn, rbpn = ufunc.pn00a(date1, date2)
+- return dpsi, deps, epsa, rb, rp, rbp, rn, rbpn
+-
+-
+-def pn00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPn00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+- epsa : double array
+- rb : double array
+- rp : double array
+- rbp : double array
+- rn : double array
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P n 0 0 b
+- - - - - - - - - -
+-
+- Precession-nutation, IAU 2000B model: a multi-purpose function,
+- supporting classical (equinox-based) use directly and CIO-based
+- use indirectly.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation (Note 2)
+- epsa double mean obliquity (Note 3)
+- rb double[3][3] frame bias matrix (Note 4)
+- rp double[3][3] precession matrix (Note 5)
+- rbp double[3][3] bias-precession matrix (Note 6)
+- rn double[3][3] nutation matrix (Note 7)
+- rbpn double[3][3] GCRS-to-true matrix (Notes 8,9)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components (luni-solar + planetary, IAU 2000B) in
+- longitude and obliquity are in radians and with respect to the
+- equinox and ecliptic of date. For more accurate results, but
+- at the cost of increased computation, use the eraPn00a function.
+- For the utmost accuracy, use the eraPn00 function, where the
+- nutation components are caller-specified.
+-
+- 3) The mean obliquity is consistent with the IAU 2000 precession.
+-
+- 4) The matrix rb transforms vectors from GCRS to J2000.0 mean
+- equator and equinox by applying frame bias.
+-
+- 5) The matrix rp transforms vectors from J2000.0 mean equator and
+- equinox to mean equator and equinox of date by applying
+- precession.
+-
+- 6) The matrix rbp transforms vectors from GCRS to mean equator and
+- equinox of date by applying frame bias then precession. It is
+- the product rp x rb.
+-
+- 7) The matrix rn transforms vectors from mean equator and equinox
+- of date to true equator and equinox of date by applying the
+- nutation (luni-solar + planetary).
+-
+- 8) The matrix rbpn transforms vectors from GCRS to true equator and
+- equinox of date. It is the product rn x rbp, applying frame
+- bias, precession and nutation in that order.
+-
+- 9) The X,Y,Z coordinates of the IAU 2000B Celestial Intermediate
+- Pole are elements (3,1-3) of the GCRS-to-true matrix,
+- i.e. rbpn[2][0-2].
+-
+- 10) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the stated order.
+-
+- Called:
+- eraNut00b nutation, IAU 2000B
+- eraPn00 bias/precession/nutation results, IAU 2000
+-
+- Reference:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003).
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps, epsa, rb, rp, rbp, rn, rbpn = ufunc.pn00b(date1, date2)
+- return dpsi, deps, epsa, rb, rp, rbp, rn, rbpn
+-
+-
+-def pn06(date1, date2, dpsi, deps):
+- """
+- Wrapper for ERFA function ``eraPn06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- dpsi : double array
+- deps : double array
+-
+- Returns
+- -------
+- epsa : double array
+- rb : double array
+- rp : double array
+- rbp : double array
+- rn : double array
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P n 0 6
+- - - - - - - - -
+-
+- Precession-nutation, IAU 2006 model: a multi-purpose function,
+- supporting classical (equinox-based) use directly and CIO-based use
+- indirectly.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- dpsi,deps double nutation (Note 2)
+-
+- Returned:
+- epsa double mean obliquity (Note 3)
+- rb double[3][3] frame bias matrix (Note 4)
+- rp double[3][3] precession matrix (Note 5)
+- rbp double[3][3] bias-precession matrix (Note 6)
+- rn double[3][3] nutation matrix (Note 7)
+- rbpn double[3][3] GCRS-to-true matrix (Note 8)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The caller is responsible for providing the nutation components;
+- they are in longitude and obliquity, in radians and are with
+- respect to the equinox and ecliptic of date. For high-accuracy
+- applications, free core nutation should be included as well as
+- any other relevant corrections to the position of the CIP.
+-
+- 3) The returned mean obliquity is consistent with the IAU 2006
+- precession.
+-
+- 4) The matrix rb transforms vectors from GCRS to J2000.0 mean
+- equator and equinox by applying frame bias.
+-
+- 5) The matrix rp transforms vectors from J2000.0 mean equator and
+- equinox to mean equator and equinox of date by applying
+- precession.
+-
+- 6) The matrix rbp transforms vectors from GCRS to mean equator and
+- equinox of date by applying frame bias then precession. It is
+- the product rp x rb.
+-
+- 7) The matrix rn transforms vectors from mean equator and equinox
+- of date to true equator and equinox of date by applying the
+- nutation (luni-solar + planetary).
+-
+- 8) The matrix rbpn transforms vectors from GCRS to true equator and
+- equinox of date. It is the product rn x rbp, applying frame
+- bias, precession and nutation in that order.
+-
+- 9) The X,Y,Z coordinates of the Celestial Intermediate Pole are
+- elements (3,1-3) of the GCRS-to-true matrix, i.e. rbpn[2][0-2].
+-
+- 10) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the stated order.
+-
+- Called:
+- eraPfw06 bias-precession F-W angles, IAU 2006
+- eraFw2m F-W angles to r-matrix
+- eraCr copy r-matrix
+- eraTr transpose r-matrix
+- eraRxr product of two r-matrices
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- epsa, rb, rp, rbp, rn, rbpn = ufunc.pn06(date1, date2, dpsi, deps)
+- return epsa, rb, rp, rbp, rn, rbpn
+-
+-
+-def pn06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPn06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsi : double array
+- deps : double array
+- epsa : double array
+- rb : double array
+- rp : double array
+- rbp : double array
+- rn : double array
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P n 0 6 a
+- - - - - - - - - -
+-
+- Precession-nutation, IAU 2006/2000A models: a multi-purpose function,
+- supporting classical (equinox-based) use directly and CIO-based use
+- indirectly.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsi,deps double nutation (Note 2)
+- epsa double mean obliquity (Note 3)
+- rb double[3][3] frame bias matrix (Note 4)
+- rp double[3][3] precession matrix (Note 5)
+- rbp double[3][3] bias-precession matrix (Note 6)
+- rn double[3][3] nutation matrix (Note 7)
+- rbpn double[3][3] GCRS-to-true matrix (Notes 8,9)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The nutation components (luni-solar + planetary, IAU 2000A) in
+- longitude and obliquity are in radians and with respect to the
+- equinox and ecliptic of date. Free core nutation is omitted;
+- for the utmost accuracy, use the eraPn06 function, where the
+- nutation components are caller-specified.
+-
+- 3) The mean obliquity is consistent with the IAU 2006 precession.
+-
+- 4) The matrix rb transforms vectors from GCRS to mean J2000.0 by
+- applying frame bias.
+-
+- 5) The matrix rp transforms vectors from mean J2000.0 to mean of
+- date by applying precession.
+-
+- 6) The matrix rbp transforms vectors from GCRS to mean of date by
+- applying frame bias then precession. It is the product rp x rb.
+-
+- 7) The matrix rn transforms vectors from mean of date to true of
+- date by applying the nutation (luni-solar + planetary).
+-
+- 8) The matrix rbpn transforms vectors from GCRS to true of date
+- (CIP/equinox). It is the product rn x rbp, applying frame bias,
+- precession and nutation in that order.
+-
+- 9) The X,Y,Z coordinates of the IAU 2006/2000A Celestial
+- Intermediate Pole are elements (3,1-3) of the GCRS-to-true
+- matrix, i.e. rbpn[2][0-2].
+-
+- 10) It is permissible to re-use the same array in the returned
+- arguments. The arrays are filled in the stated order.
+-
+- Called:
+- eraNut06a nutation, IAU 2006/2000A
+- eraPn06 bias/precession/nutation results, IAU 2006
+-
+- Reference:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsi, deps, epsa, rb, rp, rbp, rn, rbpn = ufunc.pn06a(date1, date2)
+- return dpsi, deps, epsa, rb, rp, rbp, rn, rbpn
+-
+-
+-def pnm00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPnm00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P n m 0 0 a
+- - - - - - - - - - -
+-
+- Form the matrix of precession-nutation for a given date (including
+- frame bias), equinox-based, IAU 2000A model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rbpn double[3][3] classical NPB matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rbpn * V(GCRS), where
+- the p-vector V(date) is with respect to the true equatorial triad
+- of date date1+date2 and the p-vector V(GCRS) is with respect to
+- the Geocentric Celestial Reference System (IAU, 2000).
+-
+- 3) A faster, but slightly less accurate result (about 1 mas), can be
+- obtained by using instead the eraPnm00b function.
+-
+- Called:
+- eraPn00a bias/precession/nutation, IAU 2000A
+-
+- Reference:
+-
+- IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc.
+- 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6.
+- (2000)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rbpn = ufunc.pnm00a(date1, date2)
+- return rbpn
+-
+-
+-def pnm00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPnm00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rbpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P n m 0 0 b
+- - - - - - - - - - -
+-
+- Form the matrix of precession-nutation for a given date (including
+- frame bias), equinox-based, IAU 2000B model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rbpn double[3][3] bias-precession-nutation matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rbpn * V(GCRS), where
+- the p-vector V(date) is with respect to the true equatorial triad
+- of date date1+date2 and the p-vector V(GCRS) is with respect to
+- the Geocentric Celestial Reference System (IAU, 2000).
+-
+- 3) The present function is faster, but slightly less accurate (about
+- 1 mas), than the eraPnm00a function.
+-
+- Called:
+- eraPn00b bias/precession/nutation, IAU 2000B
+-
+- Reference:
+-
+- IAU: Trans. International Astronomical Union, Vol. XXIVB; Proc.
+- 24th General Assembly, Manchester, UK. Resolutions B1.3, B1.6.
+- (2000)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rbpn = ufunc.pnm00b(date1, date2)
+- return rbpn
+-
+-
+-def pnm06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPnm06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rnpb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P n m 0 6 a
+- - - - - - - - - - -
+-
+- Form the matrix of precession-nutation for a given date (including
+- frame bias), IAU 2006 precession and IAU 2000A nutation models.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- rnpb double[3][3] bias-precession-nutation matrix (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rnpb * V(GCRS), where
+- the p-vector V(date) is with respect to the true equatorial triad
+- of date date1+date2 and the p-vector V(GCRS) is with respect to
+- the Geocentric Celestial Reference System (IAU, 2000).
+-
+- Called:
+- eraPfw06 bias-precession F-W angles, IAU 2006
+- eraNut06a nutation, IAU 2006/2000A
+- eraFw2m F-W angles to r-matrix
+-
+- Reference:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rnpb = ufunc.pnm06a(date1, date2)
+- return rnpb
+-
+-
+-def pnm80(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPnm80``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rmatpn : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P n m 8 0
+- - - - - - - - - -
+-
+- Form the matrix of precession/nutation for a given date, IAU 1976
+- precession model, IAU 1980 nutation model.
+-
+- Given:
+- date1,date2 double TDB date (Note 1)
+-
+- Returned:
+- rmatpn double[3][3] combined precession/nutation matrix
+-
+- Notes:
+-
+- 1) The TDB date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TDB)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The matrix operates in the sense V(date) = rmatpn * V(J2000),
+- where the p-vector V(date) is with respect to the true equatorial
+- triad of date date1+date2 and the p-vector V(J2000) is with
+- respect to the mean equatorial triad of epoch J2000.0.
+-
+- Called:
+- eraPmat76 precession matrix, IAU 1976
+- eraNutm80 nutation matrix, IAU 1980
+- eraRxr product of two r-matrices
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 3.3 (p145).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rmatpn = ufunc.pnm80(date1, date2)
+- return rmatpn
+-
+-
+-def pom00(xp, yp, sp):
+- """
+- Wrapper for ERFA function ``eraPom00``.
+-
+- Parameters
+- ----------
+- xp : double array
+- yp : double array
+- sp : double array
+-
+- Returns
+- -------
+- rpom : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P o m 0 0
+- - - - - - - - - - -
+-
+- Form the matrix of polar motion for a given date, IAU 2000.
+-
+- Given:
+- xp,yp double coordinates of the pole (radians, Note 1)
+- sp double the TIO locator s' (radians, Note 2)
+-
+- Returned:
+- rpom double[3][3] polar-motion matrix (Note 3)
+-
+- Notes:
+-
+- 1) The arguments xp and yp are the coordinates (in radians) of the
+- Celestial Intermediate Pole with respect to the International
+- Terrestrial Reference System (see IERS Conventions 2003),
+- measured along the meridians to 0 and 90 deg west respectively.
+-
+- 2) The argument sp is the TIO locator s', in radians, which
+- positions the Terrestrial Intermediate Origin on the equator. It
+- is obtained from polar motion observations by numerical
+- integration, and so is in essence unpredictable. However, it is
+- dominated by a secular drift of about 47 microarcseconds per
+- century, and so can be taken into account by using s' = -47*t,
+- where t is centuries since J2000.0. The function eraSp00
+- implements this approximation.
+-
+- 3) The matrix operates in the sense V(TRS) = rpom * V(CIP), meaning
+- that it is the final rotation when computing the pointing
+- direction to a celestial source.
+-
+- Called:
+- eraIr initialize r-matrix to identity
+- eraRz rotate around Z-axis
+- eraRy rotate around Y-axis
+- eraRx rotate around X-axis
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rpom = ufunc.pom00(xp, yp, sp)
+- return rpom
+-
+-
+-def pr00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraPr00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- dpsipr : double array
+- depspr : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P r 0 0
+- - - - - - - - -
+-
+- Precession-rate part of the IAU 2000 precession-nutation models
+- (part of MHB2000).
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- dpsipr,depspr double precession corrections (Notes 2,3)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The precession adjustments are expressed as "nutation
+- components", corrections in longitude and obliquity with respect
+- to the J2000.0 equinox and ecliptic.
+-
+- 3) Although the precession adjustments are stated to be with respect
+- to Lieske et al. (1977), the MHB2000 model does not specify which
+- set of Euler angles are to be used and how the adjustments are to
+- be applied. The most literal and straightforward procedure is to
+- adopt the 4-rotation epsilon_0, psi_A, omega_A, xi_A option, and
+- to add dpsipr to psi_A and depspr to both omega_A and eps_A.
+-
+- 4) This is an implementation of one aspect of the IAU 2000A nutation
+- model, formally adopted by the IAU General Assembly in 2000,
+- namely MHB2000 (Mathews et al. 2002).
+-
+- References:
+-
+- Lieske, J.H., Lederle, T., Fricke, W. & Morando, B., "Expressions
+- for the precession quantities based upon the IAU (1976) System of
+- Astronomical Constants", Astron.Astrophys., 58, 1-16 (1977)
+-
+- Mathews, P.M., Herring, T.A., Buffet, B.A., "Modeling of nutation
+- and precession New nutation series for nonrigid Earth and
+- insights into the Earth's interior", J.Geophys.Res., 107, B4,
+- 2002. The MHB2000 code itself was obtained on 9th September 2002
+- from ftp://maia.usno.navy.mil/conv2000/chapter5/IAU2000A.
+-
+- Wallace, P.T., "Software for Implementing the IAU 2000
+- Resolutions", in IERS Workshop 5.1 (2002).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dpsipr, depspr = ufunc.pr00(date1, date2)
+- return dpsipr, depspr
+-
+-
+-def prec76(date01, date02, date11, date12):
+- """
+- Wrapper for ERFA function ``eraPrec76``.
+-
+- Parameters
+- ----------
+- date01 : double array
+- date02 : double array
+- date11 : double array
+- date12 : double array
+-
+- Returns
+- -------
+- zeta : double array
+- z : double array
+- theta : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P r e c 7 6
+- - - - - - - - - - -
+-
+- IAU 1976 precession model.
+-
+- This function forms the three Euler angles which implement general
+- precession between two dates, using the IAU 1976 model (as for the
+- FK5 catalog).
+-
+- Given:
+- date01,date02 double TDB starting date (Note 1)
+- date11,date12 double TDB ending date (Note 1)
+-
+- Returned:
+- zeta double 1st rotation: radians cw around z
+- z double 3rd rotation: radians cw around z
+- theta double 2nd rotation: radians ccw around y
+-
+- Notes:
+-
+- 1) The dates date01+date02 and date11+date12 are Julian Dates,
+- apportioned in any convenient way between the arguments daten1
+- and daten2. For example, JD(TDB)=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- daten1 daten2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 method is best matched to the way the
+- argument is handled internally and will deliver the optimum
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+- The two dates may be expressed using different methods, but at
+- the risk of losing some resolution.
+-
+- 2) The accumulated precession angles zeta, z, theta are expressed
+- through canonical polynomials which are valid only for a limited
+- time span. In addition, the IAU 1976 precession rate is known to
+- be imperfect. The absolute accuracy of the present formulation
+- is better than 0.1 arcsec from 1960AD to 2040AD, better than
+- 1 arcsec from 1640AD to 2360AD, and remains below 3 arcsec for
+- the whole of the period 500BC to 3000AD. The errors exceed
+- 10 arcsec outside the range 1200BC to 3900AD, exceed 100 arcsec
+- outside 4200BC to 5600AD and exceed 1000 arcsec outside 6800BC to
+- 8200AD.
+-
+- 3) The three angles are returned in the conventional order, which
+- is not the same as the order of the corresponding Euler
+- rotations. The precession matrix is
+- R_3(-z) x R_2(+theta) x R_3(-zeta).
+-
+- Reference:
+-
+- Lieske, J.H., 1979, Astron.Astrophys. 73, 282, equations
+- (6) & (7), p283.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- zeta, z, theta = ufunc.prec76(date01, date02, date11, date12)
+- return zeta, z, theta
+-
+-
+-def s00(date1, date2, x, y):
+- """
+- Wrapper for ERFA function ``eraS00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- x : double array
+- y : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a S 0 0
+- - - - - - - -
+-
+- The CIO locator s, positioning the Celestial Intermediate Origin on
+- the equator of the Celestial Intermediate Pole, given the CIP's X,Y
+- coordinates. Compatible with IAU 2000A precession-nutation.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- x,y double CIP coordinates (Note 3)
+-
+- Returned (function value):
+- double the CIO locator s in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The CIO locator s is the difference between the right ascensions
+- of the same point in two systems: the two systems are the GCRS
+- and the CIP,CIO, and the point is the ascending node of the
+- CIP equator. The quantity s remains below 0.1 arcsecond
+- throughout 1900-2100.
+-
+- 3) The series used to compute s is in fact for s+XY/2, where X and Y
+- are the x and y components of the CIP unit vector; this series
+- is more compact than a direct series for s would be. This
+- function requires X,Y to be supplied by the caller, who is
+- responsible for providing values that are consistent with the
+- supplied date.
+-
+- 4) The model is consistent with the IAU 2000A precession-nutation.
+-
+- Called:
+- eraFal03 mean anomaly of the Moon
+- eraFalp03 mean anomaly of the Sun
+- eraFaf03 mean argument of the latitude of the Moon
+- eraFad03 mean elongation of the Moon from the Sun
+- eraFaom03 mean longitude of the Moon's ascending node
+- eraFave03 mean longitude of Venus
+- eraFae03 mean longitude of Earth
+- eraFapa03 general accumulated precession in longitude
+-
+- References:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.s00(date1, date2, x, y)
+- return c_retval
+-
+-
+-def s00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraS00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S 0 0 a
+- - - - - - - - -
+-
+- The CIO locator s, positioning the Celestial Intermediate Origin on
+- the equator of the Celestial Intermediate Pole, using the IAU 2000A
+- precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double the CIO locator s in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The CIO locator s is the difference between the right ascensions
+- of the same point in two systems. The two systems are the GCRS
+- and the CIP,CIO, and the point is the ascending node of the
+- CIP equator. The CIO locator s remains a small fraction of
+- 1 arcsecond throughout 1900-2100.
+-
+- 3) The series used to compute s is in fact for s+XY/2, where X and Y
+- are the x and y components of the CIP unit vector; this series
+- is more compact than a direct series for s would be. The present
+- function uses the full IAU 2000A nutation model when predicting
+- the CIP position. Faster results, with no significant loss of
+- accuracy, can be obtained via the function eraS00b, which uses
+- instead the IAU 2000B truncated model.
+-
+- Called:
+- eraPnm00a classical NPB matrix, IAU 2000A
+- eraBnp2xy extract CIP X,Y from the BPN matrix
+- eraS00 the CIO locator s, given X,Y, IAU 2000A
+-
+- References:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.s00a(date1, date2)
+- return c_retval
+-
+-
+-def s00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraS00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S 0 0 b
+- - - - - - - - -
+-
+- The CIO locator s, positioning the Celestial Intermediate Origin on
+- the equator of the Celestial Intermediate Pole, using the IAU 2000B
+- precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double the CIO locator s in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The CIO locator s is the difference between the right ascensions
+- of the same point in two systems. The two systems are the GCRS
+- and the CIP,CIO, and the point is the ascending node of the
+- CIP equator. The CIO locator s remains a small fraction of
+- 1 arcsecond throughout 1900-2100.
+-
+- 3) The series used to compute s is in fact for s+XY/2, where X and Y
+- are the x and y components of the CIP unit vector; this series
+- is more compact than a direct series for s would be. The present
+- function uses the IAU 2000B truncated nutation model when
+- predicting the CIP position. The function eraS00a uses instead
+- the full IAU 2000A model, but with no significant increase in
+- accuracy and at some cost in speed.
+-
+- Called:
+- eraPnm00b classical NPB matrix, IAU 2000B
+- eraBnp2xy extract CIP X,Y from the BPN matrix
+- eraS00 the CIO locator s, given X,Y, IAU 2000A
+-
+- References:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.s00b(date1, date2)
+- return c_retval
+-
+-
+-def s06(date1, date2, x, y):
+- """
+- Wrapper for ERFA function ``eraS06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- x : double array
+- y : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a S 0 6
+- - - - - - - -
+-
+- The CIO locator s, positioning the Celestial Intermediate Origin on
+- the equator of the Celestial Intermediate Pole, given the CIP's X,Y
+- coordinates. Compatible with IAU 2006/2000A precession-nutation.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- x,y double CIP coordinates (Note 3)
+-
+- Returned (function value):
+- double the CIO locator s in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The CIO locator s is the difference between the right ascensions
+- of the same point in two systems: the two systems are the GCRS
+- and the CIP,CIO, and the point is the ascending node of the
+- CIP equator. The quantity s remains below 0.1 arcsecond
+- throughout 1900-2100.
+-
+- 3) The series used to compute s is in fact for s+XY/2, where X and Y
+- are the x and y components of the CIP unit vector; this series
+- is more compact than a direct series for s would be. This
+- function requires X,Y to be supplied by the caller, who is
+- responsible for providing values that are consistent with the
+- supplied date.
+-
+- 4) The model is consistent with the "P03" precession (Capitaine et
+- al. 2003), adopted by IAU 2006 Resolution 1, 2006, and the
+- IAU 2000A nutation (with P03 adjustments).
+-
+- Called:
+- eraFal03 mean anomaly of the Moon
+- eraFalp03 mean anomaly of the Sun
+- eraFaf03 mean argument of the latitude of the Moon
+- eraFad03 mean elongation of the Moon from the Sun
+- eraFaom03 mean longitude of the Moon's ascending node
+- eraFave03 mean longitude of Venus
+- eraFae03 mean longitude of Earth
+- eraFapa03 general accumulated precession in longitude
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. & Chapront, J., 2003, Astron.
+- Astrophys. 432, 355
+-
+- McCarthy, D.D., Petit, G. (eds.) 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.s06(date1, date2, x, y)
+- return c_retval
+-
+-
+-def s06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraS06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S 0 6 a
+- - - - - - - - -
+-
+- The CIO locator s, positioning the Celestial Intermediate Origin on
+- the equator of the Celestial Intermediate Pole, using the IAU 2006
+- precession and IAU 2000A nutation models.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double the CIO locator s in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The CIO locator s is the difference between the right ascensions
+- of the same point in two systems. The two systems are the GCRS
+- and the CIP,CIO, and the point is the ascending node of the
+- CIP equator. The CIO locator s remains a small fraction of
+- 1 arcsecond throughout 1900-2100.
+-
+- 3) The series used to compute s is in fact for s+XY/2, where X and Y
+- are the x and y components of the CIP unit vector; this series is
+- more compact than a direct series for s would be. The present
+- function uses the full IAU 2000A nutation model when predicting
+- the CIP position.
+-
+- Called:
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+-
+- References:
+-
+- Capitaine, N., Chapront, J., Lambert, S. and Wallace, P.,
+- "Expressions for the Celestial Intermediate Pole and Celestial
+- Ephemeris Origin consistent with the IAU 2000A precession-
+- nutation model", Astron.Astrophys. 400, 1145-1154 (2003)
+-
+- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
+- intermediate origin" (CIO) by IAU 2006 Resolution 2.
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.s06a(date1, date2)
+- return c_retval
+-
+-
+-def sp00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraSp00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S p 0 0
+- - - - - - - - -
+-
+- The TIO locator s', positioning the Terrestrial Intermediate Origin
+- on the equator of the Celestial Intermediate Pole.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double the TIO locator s' in radians (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The TIO locator s' is obtained from polar motion observations by
+- numerical integration, and so is in essence unpredictable.
+- However, it is dominated by a secular drift of about
+- 47 microarcseconds per century, which is the approximation
+- evaluated by the present function.
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.sp00(date1, date2)
+- return c_retval
+-
+-
+-def xy06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraXy06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a X y 0 6
+- - - - - - - - -
+-
+- X,Y coordinates of celestial intermediate pole from series based
+- on IAU 2006 precession and IAU 2000A nutation.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- x,y double CIP X,Y coordinates (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The X,Y coordinates are those of the unit vector towards the
+- celestial intermediate pole. They represent the combined effects
+- of frame bias, precession and nutation.
+-
+- 3) The fundamental arguments used are as adopted in IERS Conventions
+- (2003) and are from Simon et al. (1994) and Souchay et al.
+- (1999).
+-
+- 4) This is an alternative to the angles-based method, via the ERFA
+- function eraFw2xy and as used in eraXys06a for example. The two
+- methods agree at the 1 microarcsecond level (at present), a
+- negligible amount compared with the intrinsic accuracy of the
+- models. However, it would be unwise to mix the two methods
+- (angles-based and series-based) in a single application.
+-
+- Called:
+- eraFal03 mean anomaly of the Moon
+- eraFalp03 mean anomaly of the Sun
+- eraFaf03 mean argument of the latitude of the Moon
+- eraFad03 mean elongation of the Moon from the Sun
+- eraFaom03 mean longitude of the Moon's ascending node
+- eraFame03 mean longitude of Mercury
+- eraFave03 mean longitude of Venus
+- eraFae03 mean longitude of Earth
+- eraFama03 mean longitude of Mars
+- eraFaju03 mean longitude of Jupiter
+- eraFasa03 mean longitude of Saturn
+- eraFaur03 mean longitude of Uranus
+- eraFane03 mean longitude of Neptune
+- eraFapa03 general accumulated precession in longitude
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. & Chapront, J., 2003,
+- Astron.Astrophys., 412, 567
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Simon, J.L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G. & Laskar, J., Astron.Astrophys., 1994, 282, 663
+-
+- Souchay, J., Loysel, B., Kinoshita, H., Folgueira, M., 1999,
+- Astron.Astrophys.Supp.Ser. 135, 111
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y = ufunc.xy06(date1, date2)
+- return x, y
+-
+-
+-def xys00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraXys00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+- s : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a X y s 0 0 a
+- - - - - - - - - - -
+-
+- For a given TT date, compute the X,Y coordinates of the Celestial
+- Intermediate Pole and the CIO locator s, using the IAU 2000A
+- precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- x,y double Celestial Intermediate Pole (Note 2)
+- s double the CIO locator s (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The Celestial Intermediate Pole coordinates are the x,y
+- components of the unit vector in the Geocentric Celestial
+- Reference System.
+-
+- 3) The CIO locator s (in radians) positions the Celestial
+- Intermediate Origin on the equator of the CIP.
+-
+- 4) A faster, but slightly less accurate result (about 1 mas for
+- X,Y), can be obtained by using instead the eraXys00b function.
+-
+- Called:
+- eraPnm00a classical NPB matrix, IAU 2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS00 the CIO locator s, given X,Y, IAU 2000A
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y, s = ufunc.xys00a(date1, date2)
+- return x, y, s
+-
+-
+-def xys00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraXys00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+- s : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a X y s 0 0 b
+- - - - - - - - - - -
+-
+- For a given TT date, compute the X,Y coordinates of the Celestial
+- Intermediate Pole and the CIO locator s, using the IAU 2000B
+- precession-nutation model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- x,y double Celestial Intermediate Pole (Note 2)
+- s double the CIO locator s (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The Celestial Intermediate Pole coordinates are the x,y
+- components of the unit vector in the Geocentric Celestial
+- Reference System.
+-
+- 3) The CIO locator s (in radians) positions the Celestial
+- Intermediate Origin on the equator of the CIP.
+-
+- 4) The present function is faster, but slightly less accurate (about
+- 1 mas in X,Y), than the eraXys00a function.
+-
+- Called:
+- eraPnm00b classical NPB matrix, IAU 2000B
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS00 the CIO locator s, given X,Y, IAU 2000A
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y, s = ufunc.xys00b(date1, date2)
+- return x, y, s
+-
+-
+-def xys06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraXys06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- x : double array
+- y : double array
+- s : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a X y s 0 6 a
+- - - - - - - - - - -
+-
+- For a given TT date, compute the X,Y coordinates of the Celestial
+- Intermediate Pole and the CIO locator s, using the IAU 2006
+- precession and IAU 2000A nutation models.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- x,y double Celestial Intermediate Pole (Note 2)
+- s double the CIO locator s (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The Celestial Intermediate Pole coordinates are the x,y components
+- of the unit vector in the Geocentric Celestial Reference System.
+-
+- 3) The CIO locator s (in radians) positions the Celestial
+- Intermediate Origin on the equator of the CIP.
+-
+- 4) Series-based solutions for generating X and Y are also available:
+- see Capitaine & Wallace (2006) and eraXy06.
+-
+- Called:
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+-
+- References:
+-
+- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- x, y, s = ufunc.xys06a(date1, date2)
+- return x, y, s
+-
+-
+-def ee00(date1, date2, epsa, dpsi):
+- """
+- Wrapper for ERFA function ``eraEe00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- epsa : double array
+- dpsi : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a E e 0 0
+- - - - - - - - -
+-
+- The equation of the equinoxes, compatible with IAU 2000 resolutions,
+- given the nutation in longitude and the mean obliquity.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+- epsa double mean obliquity (Note 2)
+- dpsi double nutation in longitude (Note 3)
+-
+- Returned (function value):
+- double equation of the equinoxes (Note 4)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The obliquity, in radians, is mean of date.
+-
+- 3) The result, which is in radians, operates in the following sense:
+-
+- Greenwich apparent ST = GMST + equation of the equinoxes
+-
+- 4) The result is compatible with the IAU 2000 resolutions. For
+- further details, see IERS Conventions 2003 and Capitaine et al.
+- (2002).
+-
+- Called:
+- eraEect00 equation of the equinoxes complementary terms
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.ee00(date1, date2, epsa, dpsi)
+- return c_retval
+-
+-
+-def ee00a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEe00a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E e 0 0 a
+- - - - - - - - - -
+-
+- Equation of the equinoxes, compatible with IAU 2000 resolutions.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double equation of the equinoxes (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result, which is in radians, operates in the following sense:
+-
+- Greenwich apparent ST = GMST + equation of the equinoxes
+-
+- 3) The result is compatible with the IAU 2000 resolutions. For
+- further details, see IERS Conventions 2003 and Capitaine et al.
+- (2002).
+-
+- Called:
+- eraPr00 IAU 2000 precession adjustments
+- eraObl80 mean obliquity, IAU 1980
+- eraNut00a nutation, IAU 2000A
+- eraEe00 equation of the equinoxes, IAU 2000
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003).
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.ee00a(date1, date2)
+- return c_retval
+-
+-
+-def ee00b(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEe00b``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E e 0 0 b
+- - - - - - - - - -
+-
+- Equation of the equinoxes, compatible with IAU 2000 resolutions but
+- using the truncated nutation model IAU 2000B.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double equation of the equinoxes (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result, which is in radians, operates in the following sense:
+-
+- Greenwich apparent ST = GMST + equation of the equinoxes
+-
+- 3) The result is compatible with the IAU 2000 resolutions except
+- that accuracy has been compromised for the sake of speed. For
+- further details, see McCarthy & Luzum (2001), IERS Conventions
+- 2003 and Capitaine et al. (2003).
+-
+- Called:
+- eraPr00 IAU 2000 precession adjustments
+- eraObl80 mean obliquity, IAU 1980
+- eraNut00b nutation, IAU 2000B
+- eraEe00 equation of the equinoxes, IAU 2000
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003)
+-
+- McCarthy, D.D. & Luzum, B.J., "An abridged model of the
+- precession-nutation of the celestial pole", Celestial Mechanics &
+- Dynamical Astronomy, 85, 37-49 (2003)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.ee00b(date1, date2)
+- return c_retval
+-
+-
+-def ee06a(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEe06a``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E e 0 6 a
+- - - - - - - - - -
+-
+- Equation of the equinoxes, compatible with IAU 2000 resolutions and
+- IAU 2006/2000A precession-nutation.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double equation of the equinoxes (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result, which is in radians, operates in the following sense:
+-
+- Greenwich apparent ST = GMST + equation of the equinoxes
+-
+- Called:
+- eraAnpm normalize angle into range +/- pi
+- eraGst06a Greenwich apparent sidereal time, IAU 2006/2000A
+- eraGmst06 Greenwich mean sidereal time, IAU 2006
+-
+- Reference:
+-
+- McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.ee06a(date1, date2)
+- return c_retval
+-
+-
+-def eect00(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEect00``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E e c t 0 0
+- - - - - - - - - - -
+-
+- Equation of the equinoxes complementary terms, consistent with
+- IAU 2000 resolutions.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian Date (Note 1)
+-
+- Returned (function value):
+- double complementary terms (Note 2)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The "complementary terms" are part of the equation of the
+- equinoxes (EE), classically the difference between apparent and
+- mean Sidereal Time:
+-
+- GAST = GMST + EE
+-
+- with:
+-
+- EE = dpsi * cos(eps)
+-
+- where dpsi is the nutation in longitude and eps is the obliquity
+- of date. However, if the rotation of the Earth were constant in
+- an inertial frame the classical formulation would lead to
+- apparent irregularities in the UT1 timescale traceable to side-
+- effects of precession-nutation. In order to eliminate these
+- effects from UT1, "complementary terms" were introduced in 1994
+- (IAU, 1994) and took effect from 1997 (Capitaine and Gontier,
+- 1993):
+-
+- GAST = GMST + CT + EE
+-
+- By convention, the complementary terms are included as part of
+- the equation of the equinoxes rather than as part of the mean
+- Sidereal Time. This slightly compromises the "geometrical"
+- interpretation of mean sidereal time but is otherwise
+- inconsequential.
+-
+- The present function computes CT in the above expression,
+- compatible with IAU 2000 resolutions (Capitaine et al., 2002, and
+- IERS Conventions 2003).
+-
+- Called:
+- eraFal03 mean anomaly of the Moon
+- eraFalp03 mean anomaly of the Sun
+- eraFaf03 mean argument of the latitude of the Moon
+- eraFad03 mean elongation of the Moon from the Sun
+- eraFaom03 mean longitude of the Moon's ascending node
+- eraFave03 mean longitude of Venus
+- eraFae03 mean longitude of Earth
+- eraFapa03 general accumulated precession in longitude
+-
+- References:
+-
+- Capitaine, N. & Gontier, A.-M., Astron.Astrophys., 275,
+- 645-650 (1993)
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astron.Astrophys., 406,
+- 1135-1149 (2003)
+-
+- IAU Resolution C7, Recommendation 3 (1994)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.eect00(date1, date2)
+- return c_retval
+-
+-
+-def eqeq94(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEqeq94``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E q e q 9 4
+- - - - - - - - - - -
+-
+- Equation of the equinoxes, IAU 1994 model.
+-
+- Given:
+- date1,date2 double TDB date (Note 1)
+-
+- Returned (function value):
+- double equation of the equinoxes (Note 2)
+-
+- Notes:
+-
+- 1) The date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The result, which is in radians, operates in the following sense:
+-
+- Greenwich apparent ST = GMST + equation of the equinoxes
+-
+- Called:
+- eraAnpm normalize angle into range +/- pi
+- eraNut80 nutation, IAU 1980
+- eraObl80 mean obliquity, IAU 1980
+-
+- References:
+-
+- IAU Resolution C7, Recommendation 3 (1994).
+-
+- Capitaine, N. & Gontier, A.-M., 1993, Astron.Astrophys., 275,
+- 645-650.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.eqeq94(date1, date2)
+- return c_retval
+-
+-
+-def era00(dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraEra00``.
+-
+- Parameters
+- ----------
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E r a 0 0
+- - - - - - - - - -
+-
+- Earth rotation angle (IAU 2000 model).
+-
+- Given:
+- dj1,dj2 double UT1 as a 2-part Julian Date (see note)
+-
+- Returned (function value):
+- double Earth rotation angle (radians), range 0-2pi
+-
+- Notes:
+-
+- 1) The UT1 date dj1+dj2 is a Julian Date, apportioned in any
+- convenient way between the arguments dj1 and dj2. For example,
+- JD(UT1)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- dj1 dj2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. The date & time method is
+- best matched to the algorithm used: maximum precision is
+- delivered when the dj1 argument is for 0hrs UT1 on the day in
+- question and the dj2 argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) The algorithm is adapted from Expression 22 of Capitaine et al.
+- 2000. The time argument has been expressed in days directly,
+- and, to retain precision, integer contributions have been
+- eliminated. The same formulation is given in IERS Conventions
+- (2003), Chap. 5, Eq. 14.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Capitaine N., Guinot B. and McCarthy D.D, 2000, Astron.
+- Astrophys., 355, 398-405.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.era00(dj1, dj2)
+- return c_retval
+-
+-
+-def gmst00(uta, utb, tta, ttb):
+- """
+- Wrapper for ERFA function ``eraGmst00``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+- tta : double array
+- ttb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G m s t 0 0
+- - - - - - - - - - -
+-
+- Greenwich mean sidereal time (model consistent with IAU 2000
+- resolutions).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+- tta,ttb double TT as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich mean sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both
+- Julian Dates, apportioned in any convenient way between the
+- argument pairs. For example, JD=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- Part A Part B
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable (in the case of UT; the TT is not at all critical
+- in this respect). The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- Rotation Angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) Both UT1 and TT are required, UT1 to predict the Earth rotation
+- and TT to predict the effects of precession. If UT1 is used for
+- both purposes, errors of order 100 microarcseconds result.
+-
+- 3) This GMST is compatible with the IAU 2000 resolutions and must be
+- used only in conjunction with other IAU 2000 compatible
+- components such as precession-nutation and equation of the
+- equinoxes.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- 5) The algorithm is from Capitaine et al. (2003) and IERS
+- Conventions 2003.
+-
+- Called:
+- eraEra00 Earth rotation angle, IAU 2000
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gmst00(uta, utb, tta, ttb)
+- return c_retval
+-
+-
+-def gmst06(uta, utb, tta, ttb):
+- """
+- Wrapper for ERFA function ``eraGmst06``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+- tta : double array
+- ttb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G m s t 0 6
+- - - - - - - - - - -
+-
+- Greenwich mean sidereal time (consistent with IAU 2006 precession).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+- tta,ttb double TT as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich mean sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both
+- Julian Dates, apportioned in any convenient way between the
+- argument pairs. For example, JD=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- Part A Part B
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable (in the case of UT; the TT is not at all critical
+- in this respect). The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- rotation angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) Both UT1 and TT are required, UT1 to predict the Earth rotation
+- and TT to predict the effects of precession. If UT1 is used for
+- both purposes, errors of order 100 microarcseconds result.
+-
+- 3) This GMST is compatible with the IAU 2006 precession and must not
+- be used with other precession models.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- Called:
+- eraEra00 Earth rotation angle, IAU 2000
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Reference:
+-
+- Capitaine, N., Wallace, P.T. & Chapront, J., 2005,
+- Astron.Astrophys. 432, 355
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gmst06(uta, utb, tta, ttb)
+- return c_retval
+-
+-
+-def gmst82(dj1, dj2):
+- """
+- Wrapper for ERFA function ``eraGmst82``.
+-
+- Parameters
+- ----------
+- dj1 : double array
+- dj2 : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G m s t 8 2
+- - - - - - - - - - -
+-
+- Universal Time to Greenwich mean sidereal time (IAU 1982 model).
+-
+- Given:
+- dj1,dj2 double UT1 Julian Date (see note)
+-
+- Returned (function value):
+- double Greenwich mean sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 date dj1+dj2 is a Julian Date, apportioned in any
+- convenient way between the arguments dj1 and dj2. For example,
+- JD(UT1)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- dj1 dj2
+-
+- 2450123.7 0 (JD method)
+- 2451545 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. The date & time method is
+- best matched to the algorithm used: maximum accuracy (or, at
+- least, minimum noise) is delivered when the dj1 argument is for
+- 0hrs UT1 on the day in question and the dj2 argument lies in the
+- range 0 to 1, or vice versa.
+-
+- 2) The algorithm is based on the IAU 1982 expression. This is
+- always described as giving the GMST at 0 hours UT1. In fact, it
+- gives the difference between the GMST and the UT, the steady
+- 4-minutes-per-day drawing-ahead of ST with respect to UT. When
+- whole days are ignored, the expression happens to equal the GMST
+- at 0 hours UT1 each day.
+-
+- 3) In this function, the entire UT1 (the sum of the two arguments
+- dj1 and dj2) is used directly as the argument for the standard
+- formula, the constant term of which is adjusted by 12 hours to
+- take account of the noon phasing of Julian Date. The UT1 is then
+- added, but omitting whole days to conserve accuracy.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Transactions of the International Astronomical Union,
+- XVIII B, 67 (1983).
+-
+- Aoki et al., Astron.Astrophys., 105, 359-361 (1982).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gmst82(dj1, dj2)
+- return c_retval
+-
+-
+-def gst00a(uta, utb, tta, ttb):
+- """
+- Wrapper for ERFA function ``eraGst00a``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+- tta : double array
+- ttb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G s t 0 0 a
+- - - - - - - - - - -
+-
+- Greenwich apparent sidereal time (consistent with IAU 2000
+- resolutions).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+- tta,ttb double TT as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich apparent sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both
+- Julian Dates, apportioned in any convenient way between the
+- argument pairs. For example, JD=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- Part A Part B
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable (in the case of UT; the TT is not at all critical
+- in this respect). The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- Rotation Angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) Both UT1 and TT are required, UT1 to predict the Earth rotation
+- and TT to predict the effects of precession-nutation. If UT1 is
+- used for both purposes, errors of order 100 microarcseconds
+- result.
+-
+- 3) This GAST is compatible with the IAU 2000 resolutions and must be
+- used only in conjunction with other IAU 2000 compatible
+- components such as precession-nutation.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- 5) The algorithm is from Capitaine et al. (2003) and IERS
+- Conventions 2003.
+-
+- Called:
+- eraGmst00 Greenwich mean sidereal time, IAU 2000
+- eraEe00a equation of the equinoxes, IAU 2000A
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gst00a(uta, utb, tta, ttb)
+- return c_retval
+-
+-
+-def gst00b(uta, utb):
+- """
+- Wrapper for ERFA function ``eraGst00b``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G s t 0 0 b
+- - - - - - - - - - -
+-
+- Greenwich apparent sidereal time (consistent with IAU 2000
+- resolutions but using the truncated nutation model IAU 2000B).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich apparent sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 date uta+utb is a Julian Date, apportioned in any
+- convenient way between the argument pair. For example,
+- JD=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- Rotation Angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) The result is compatible with the IAU 2000 resolutions, except
+- that accuracy has been compromised for the sake of speed and
+- convenience in two respects:
+-
+- . UT is used instead of TDB (or TT) to compute the precession
+- component of GMST and the equation of the equinoxes. This
+- results in errors of order 0.1 mas at present.
+-
+- . The IAU 2000B abridged nutation model (McCarthy & Luzum, 2001)
+- is used, introducing errors of up to 1 mas.
+-
+- 3) This GAST is compatible with the IAU 2000 resolutions and must be
+- used only in conjunction with other IAU 2000 compatible
+- components such as precession-nutation.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- 5) The algorithm is from Capitaine et al. (2003) and IERS
+- Conventions 2003.
+-
+- Called:
+- eraGmst00 Greenwich mean sidereal time, IAU 2000
+- eraEe00b equation of the equinoxes, IAU 2000B
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Capitaine, N., Wallace, P.T. and McCarthy, D.D., "Expressions to
+- implement the IAU 2000 definition of UT1", Astronomy &
+- Astrophysics, 406, 1135-1149 (2003)
+-
+- McCarthy, D.D. & Luzum, B.J., "An abridged model of the
+- precession-nutation of the celestial pole", Celestial Mechanics &
+- Dynamical Astronomy, 85, 37-49 (2003)
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gst00b(uta, utb)
+- return c_retval
+-
+-
+-def gst06(uta, utb, tta, ttb, rnpb):
+- """
+- Wrapper for ERFA function ``eraGst06``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+- tta : double array
+- ttb : double array
+- rnpb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a G s t 0 6
+- - - - - - - - - -
+-
+- Greenwich apparent sidereal time, IAU 2006, given the NPB matrix.
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+- tta,ttb double TT as a 2-part Julian Date (Notes 1,2)
+- rnpb double[3][3] nutation x precession x bias matrix
+-
+- Returned (function value):
+- double Greenwich apparent sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both
+- Julian Dates, apportioned in any convenient way between the
+- argument pairs. For example, JD=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- Part A Part B
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable (in the case of UT; the TT is not at all critical
+- in this respect). The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- rotation angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) Both UT1 and TT are required, UT1 to predict the Earth rotation
+- and TT to predict the effects of precession-nutation. If UT1 is
+- used for both purposes, errors of order 100 microarcseconds
+- result.
+-
+- 3) Although the function uses the IAU 2006 series for s+XY/2, it is
+- otherwise independent of the precession-nutation model and can in
+- practice be used with any equinox-based NPB matrix.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- Called:
+- eraBpn2xy extract CIP X,Y coordinates from NPB matrix
+- eraS06 the CIO locator s, given X,Y, IAU 2006
+- eraAnp normalize angle into range 0 to 2pi
+- eraEra00 Earth rotation angle, IAU 2000
+- eraEors equation of the origins, given NPB matrix and s
+-
+- Reference:
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gst06(uta, utb, tta, ttb, rnpb)
+- return c_retval
+-
+-
+-def gst06a(uta, utb, tta, ttb):
+- """
+- Wrapper for ERFA function ``eraGst06a``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+- tta : double array
+- ttb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G s t 0 6 a
+- - - - - - - - - - -
+-
+- Greenwich apparent sidereal time (consistent with IAU 2000 and 2006
+- resolutions).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+- tta,ttb double TT as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich apparent sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 and TT dates uta+utb and tta+ttb respectively, are both
+- Julian Dates, apportioned in any convenient way between the
+- argument pairs. For example, JD=2450123.7 could be expressed in
+- any of these ways, among others:
+-
+- Part A Part B
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable (in the case of UT; the TT is not at all critical
+- in this respect). The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- rotation angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) Both UT1 and TT are required, UT1 to predict the Earth rotation
+- and TT to predict the effects of precession-nutation. If UT1 is
+- used for both purposes, errors of order 100 microarcseconds
+- result.
+-
+- 3) This GAST is compatible with the IAU 2000/2006 resolutions and
+- must be used only in conjunction with IAU 2006 precession and
+- IAU 2000A nutation.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- Called:
+- eraPnm06a classical NPB matrix, IAU 2006/2000A
+- eraGst06 Greenwich apparent ST, IAU 2006, given NPB matrix
+-
+- Reference:
+-
+- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gst06a(uta, utb, tta, ttb)
+- return c_retval
+-
+-
+-def gst94(uta, utb):
+- """
+- Wrapper for ERFA function ``eraGst94``.
+-
+- Parameters
+- ----------
+- uta : double array
+- utb : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a G s t 9 4
+- - - - - - - - - -
+-
+- Greenwich apparent sidereal time (consistent with IAU 1982/94
+- resolutions).
+-
+- Given:
+- uta,utb double UT1 as a 2-part Julian Date (Notes 1,2)
+-
+- Returned (function value):
+- double Greenwich apparent sidereal time (radians)
+-
+- Notes:
+-
+- 1) The UT1 date uta+utb is a Julian Date, apportioned in any
+- convenient way between the argument pair. For example,
+- JD=2450123.7 could be expressed in any of these ways, among
+- others:
+-
+- uta utb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in cases
+- where the loss of several decimal digits of resolution is
+- acceptable. The J2000 and MJD methods are good compromises
+- between resolution and convenience. For UT, the date & time
+- method is best matched to the algorithm that is used by the Earth
+- Rotation Angle function, called internally: maximum precision is
+- delivered when the uta argument is for 0hrs UT1 on the day in
+- question and the utb argument lies in the range 0 to 1, or vice
+- versa.
+-
+- 2) The result is compatible with the IAU 1982 and 1994 resolutions,
+- except that accuracy has been compromised for the sake of
+- convenience in that UT is used instead of TDB (or TT) to compute
+- the equation of the equinoxes.
+-
+- 3) This GAST must be used only in conjunction with contemporaneous
+- IAU standards such as 1976 precession, 1980 obliquity and 1982
+- nutation. It is not compatible with the IAU 2000 resolutions.
+-
+- 4) The result is returned in the range 0 to 2pi.
+-
+- Called:
+- eraGmst82 Greenwich mean sidereal time, IAU 1982
+- eraEqeq94 equation of the equinoxes, IAU 1994
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- IAU Resolution C7, Recommendation 3 (1994)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.gst94(uta, utb)
+- return c_retval
+-
+-
+-def pvstar(pv):
+- """
+- Wrapper for ERFA function ``eraPvstar``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- ra : double array
+- dec : double array
+- pmr : double array
+- pmd : double array
+- px : double array
+- rv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P v s t a r
+- - - - - - - - - - -
+-
+- Convert star position+velocity vector to catalog coordinates.
+-
+- Given (Note 1):
+- pv double[2][3] pv-vector (au, au/day)
+-
+- Returned (Note 2):
+- ra double right ascension (radians)
+- dec double declination (radians)
+- pmr double RA proper motion (radians/year)
+- pmd double Dec proper motion (radians/year)
+- px double parallax (arcsec)
+- rv double radial velocity (km/s, positive = receding)
+-
+- Returned (function value):
+- int status:
+- 0 = OK
+- -1 = superluminal speed (Note 5)
+- -2 = null position vector
+-
+- Notes:
+-
+- 1) The specified pv-vector is the coordinate direction (and its rate
+- of change) for the date at which the light leaving the star
+- reached the solar-system barycenter.
+-
+- 2) The star data returned by this function are "observables" for an
+- imaginary observer at the solar-system barycenter. Proper motion
+- and radial velocity are, strictly, in terms of barycentric
+- coordinate time, TCB. For most practical applications, it is
+- permissible to neglect the distinction between TCB and ordinary
+- "proper" time on Earth (TT/TAI). The result will, as a rule, be
+- limited by the intrinsic accuracy of the proper-motion and
+- radial-velocity data; moreover, the supplied pv-vector is likely
+- to be merely an intermediate result (for example generated by the
+- function eraStarpv), so that a change of time unit will cancel
+- out overall.
+-
+- In accordance with normal star-catalog conventions, the object's
+- right ascension and declination are freed from the effects of
+- secular aberration. The frame, which is aligned to the catalog
+- equator and equinox, is Lorentzian and centered on the SSB.
+-
+- Summarizing, the specified pv-vector is for most stars almost
+- identical to the result of applying the standard geometrical
+- "space motion" transformation to the catalog data. The
+- differences, which are the subject of the Stumpff paper cited
+- below, are:
+-
+- (i) In stars with significant radial velocity and proper motion,
+- the constantly changing light-time distorts the apparent proper
+- motion. Note that this is a classical, not a relativistic,
+- effect.
+-
+- (ii) The transformation complies with special relativity.
+-
+- 3) Care is needed with units. The star coordinates are in radians
+- and the proper motions in radians per Julian year, but the
+- parallax is in arcseconds; the radial velocity is in km/s, but
+- the pv-vector result is in au and au/day.
+-
+- 4) The proper motions are the rate of change of the right ascension
+- and declination at the catalog epoch and are in radians per Julian
+- year. The RA proper motion is in terms of coordinate angle, not
+- true angle, and will thus be numerically larger at high
+- declinations.
+-
+- 5) Straight-line motion at constant speed in the inertial frame is
+- assumed. If the speed is greater than or equal to the speed of
+- light, the function aborts with an error status.
+-
+- 6) The inverse transformation is performed by the function eraStarpv.
+-
+- Called:
+- eraPn decompose p-vector into modulus and direction
+- eraPdp scalar product of two p-vectors
+- eraSxp multiply p-vector by scalar
+- eraPmp p-vector minus p-vector
+- eraPm modulus of p-vector
+- eraPpp p-vector plus p-vector
+- eraPv2s pv-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Reference:
+-
+- Stumpff, P., 1985, Astron.Astrophys. 144, 232-240.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ra, dec, pmr, pmd, px, rv, c_retval = ufunc.pvstar(pv)
+- check_errwarn(c_retval, 'pvstar')
+- return ra, dec, pmr, pmd, px, rv
+-
+-
+-STATUS_CODES['pvstar'] = {0: 'OK', -1: 'superluminal speed (Note 5)', -2: 'null position vector'}
+-
+-
+-def starpv(ra, dec, pmr, pmd, px, rv):
+- """
+- Wrapper for ERFA function ``eraStarpv``.
+-
+- Parameters
+- ----------
+- ra : double array
+- dec : double array
+- pmr : double array
+- pmd : double array
+- px : double array
+- rv : double array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a S t a r p v
+- - - - - - - - - - -
+-
+- Convert star catalog coordinates to position+velocity vector.
+-
+- Given (Note 1):
+- ra double right ascension (radians)
+- dec double declination (radians)
+- pmr double RA proper motion (radians/year)
+- pmd double Dec proper motion (radians/year)
+- px double parallax (arcseconds)
+- rv double radial velocity (km/s, positive = receding)
+-
+- Returned (Note 2):
+- pv double[2][3] pv-vector (au, au/day)
+-
+- Returned (function value):
+- int status:
+- 0 = no warnings
+- 1 = distance overridden (Note 6)
+- 2 = excessive speed (Note 7)
+- 4 = solution didn't converge (Note 8)
+- else = binary logical OR of the above
+-
+- Notes:
+-
+- 1) The star data accepted by this function are "observables" for an
+- imaginary observer at the solar-system barycenter. Proper motion
+- and radial velocity are, strictly, in terms of barycentric
+- coordinate time, TCB. For most practical applications, it is
+- permissible to neglect the distinction between TCB and ordinary
+- "proper" time on Earth (TT/TAI). The result will, as a rule, be
+- limited by the intrinsic accuracy of the proper-motion and
+- radial-velocity data; moreover, the pv-vector is likely to be
+- merely an intermediate result, so that a change of time unit
+- would cancel out overall.
+-
+- In accordance with normal star-catalog conventions, the object's
+- right ascension and declination are freed from the effects of
+- secular aberration. The frame, which is aligned to the catalog
+- equator and equinox, is Lorentzian and centered on the SSB.
+-
+- 2) The resulting position and velocity pv-vector is with respect to
+- the same frame and, like the catalog coordinates, is freed from
+- the effects of secular aberration. Should the "coordinate
+- direction", where the object was located at the catalog epoch, be
+- required, it may be obtained by calculating the magnitude of the
+- position vector pv[0][0-2] dividing by the speed of light in
+- au/day to give the light-time, and then multiplying the space
+- velocity pv[1][0-2] by this light-time and adding the result to
+- pv[0][0-2].
+-
+- Summarizing, the pv-vector returned is for most stars almost
+- identical to the result of applying the standard geometrical
+- "space motion" transformation. The differences, which are the
+- subject of the Stumpff paper referenced below, are:
+-
+- (i) In stars with significant radial velocity and proper motion,
+- the constantly changing light-time distorts the apparent proper
+- motion. Note that this is a classical, not a relativistic,
+- effect.
+-
+- (ii) The transformation complies with special relativity.
+-
+- 3) Care is needed with units. The star coordinates are in radians
+- and the proper motions in radians per Julian year, but the
+- parallax is in arcseconds; the radial velocity is in km/s, but
+- the pv-vector result is in au and au/day.
+-
+- 4) The RA proper motion is in terms of coordinate angle, not true
+- angle. If the catalog uses arcseconds for both RA and Dec proper
+- motions, the RA proper motion will need to be divided by cos(Dec)
+- before use.
+-
+- 5) Straight-line motion at constant speed, in the inertial frame,
+- is assumed.
+-
+- 6) An extremely small (or zero or negative) parallax is interpreted
+- to mean that the object is on the "celestial sphere", the radius
+- of which is an arbitrary (large) value (see the constant PXMIN).
+- When the distance is overridden in this way, the status,
+- initially zero, has 1 added to it.
+-
+- 7) If the space velocity is a significant fraction of c (see the
+- constant VMAX), it is arbitrarily set to zero. When this action
+- occurs, 2 is added to the status.
+-
+- 8) The relativistic adjustment involves an iterative calculation.
+- If the process fails to converge within a set number (IMAX) of
+- iterations, 4 is added to the status.
+-
+- 9) The inverse transformation is performed by the function
+- eraPvstar.
+-
+- Called:
+- eraS2pv spherical coordinates to pv-vector
+- eraPm modulus of p-vector
+- eraZp zero p-vector
+- eraPn decompose p-vector into modulus and direction
+- eraPdp scalar product of two p-vectors
+- eraSxp multiply p-vector by scalar
+- eraPmp p-vector minus p-vector
+- eraPpp p-vector plus p-vector
+-
+- Reference:
+-
+- Stumpff, P., 1985, Astron.Astrophys. 144, 232-240.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv, c_retval = ufunc.starpv(ra, dec, pmr, pmd, px, rv)
+- check_errwarn(c_retval, 'starpv')
+- return pv
+-
+-
+-STATUS_CODES['starpv'] = {0: 'no warnings', 1: 'distance overridden (Note 6)', 2: 'excessive speed (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above'}
+-
+-
+-def fk425(r1950, d1950, dr1950, dd1950, p1950, v1950):
+- """
+- Wrapper for ERFA function ``eraFk425``.
+-
+- Parameters
+- ----------
+- r1950 : double array
+- d1950 : double array
+- dr1950 : double array
+- dd1950 : double array
+- p1950 : double array
+- v1950 : double array
+-
+- Returns
+- -------
+- r2000 : double array
+- d2000 : double array
+- dr2000 : double array
+- dd2000 : double array
+- p2000 : double array
+- v2000 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 4 2 5
+- - - - - - - - - -
+-
+- Convert B1950.0 FK4 star catalog data to J2000.0 FK5.
+-
+- This function converts a star's catalog data from the old FK4
+- (Bessel-Newcomb) system to the later IAU 1976 FK5 (Fricke) system.
+-
+- Given: (all B1950.0, FK4)
+- r1950,d1950 double B1950.0 RA,Dec (rad)
+- dr1950,dd1950 double B1950.0 proper motions (rad/trop.yr)
+- p1950 double parallax (arcsec)
+- v1950 double radial velocity (km/s, +ve = moving away)
+-
+- Returned: (all J2000.0, FK5)
+- r2000,d2000 double J2000.0 RA,Dec (rad)
+- dr2000,dd2000 double J2000.0 proper motions (rad/Jul.yr)
+- p2000 double parallax (arcsec)
+- v2000 double radial velocity (km/s, +ve = moving away)
+-
+- Notes:
+-
+- 1) The proper motions in RA are dRA/dt rather than cos(Dec)*dRA/dt,
+- and are per year rather than per century.
+-
+- 2) The conversion is somewhat complicated, for several reasons:
+-
+- . Change of standard epoch from B1950.0 to J2000.0.
+-
+- . An intermediate transition date of 1984 January 1.0 TT.
+-
+- . A change of precession model.
+-
+- . Change of time unit for proper motion (tropical to Julian).
+-
+- . FK4 positions include the E-terms of aberration, to simplify
+- the hand computation of annual aberration. FK5 positions
+- assume a rigorous aberration computation based on the Earth's
+- barycentric velocity.
+-
+- . The E-terms also affect proper motions, and in particular cause
+- objects at large distances to exhibit fictitious proper
+- motions.
+-
+- The algorithm is based on Smith et al. (1989) and Yallop et al.
+- (1989), which presented a matrix method due to Standish (1982) as
+- developed by Aoki et al. (1983), using Kinoshita's development of
+- Andoyer's post-Newcomb precession. The numerical constants from
+- Seidelmann (1992) are used canonically.
+-
+- 3) Conversion from B1950.0 FK4 to J2000.0 FK5 only is provided for.
+- Conversions for different epochs and equinoxes would require
+- additional treatment for precession, proper motion and E-terms.
+-
+- 4) In the FK4 catalog the proper motions of stars within 10 degrees
+- of the poles do not embody differential E-terms effects and
+- should, strictly speaking, be handled in a different manner from
+- stars outside these regions. However, given the general lack of
+- homogeneity of the star data available for routine astrometry,
+- the difficulties of handling positions that may have been
+- determined from astrometric fields spanning the polar and non-
+- polar regions, the likelihood that the differential E-terms
+- effect was not taken into account when allowing for proper motion
+- in past astrometry, and the undesirability of a discontinuity in
+- the algorithm, the decision has been made in this ERFA algorithm
+- to include the effects of differential E-terms on the proper
+- motions for all stars, whether polar or not. At epoch J2000.0,
+- and measuring "on the sky" rather than in terms of RA change, the
+- errors resulting from this simplification are less than
+- 1 milliarcsecond in position and 1 milliarcsecond per century in
+- proper motion.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraPv2s pv-vector to spherical coordinates
+- eraPdp scalar product of two p-vectors
+- eraPvmpv pv-vector minus pv_vector
+- eraPvppv pv-vector plus pv_vector
+- eraS2pv spherical coordinates to pv-vector
+- eraSxp multiply p-vector by scalar
+-
+- References:
+-
+- Aoki, S. et al., 1983, "Conversion matrix of epoch B1950.0
+- FK4-based positions of stars to epoch J2000.0 positions in
+- accordance with the new IAU resolutions". Astron.Astrophys.
+- 128, 263-267.
+-
+- Seidelmann, P.K. (ed), 1992, "Explanatory Supplement to the
+- Astronomical Almanac", ISBN 0-935702-68-7.
+-
+- Smith, C.A. et al., 1989, "The transformation of astrometric
+- catalog systems to the equinox J2000.0". Astron.J. 97, 265.
+-
+- Standish, E.M., 1982, "Conversion of positions and proper motions
+- from B1950.0 to the IAU system at J2000.0". Astron.Astrophys.,
+- 115, 1, 20-22.
+-
+- Yallop, B.D. et al., 1989, "Transformation of mean star places
+- from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space".
+- Astron.J. 97, 274.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r2000, d2000, dr2000, dd2000, p2000, v2000 = ufunc.fk425(r1950, d1950, dr1950, dd1950, p1950, v1950)
+- return r2000, d2000, dr2000, dd2000, p2000, v2000
+-
+-
+-def fk45z(r1950, d1950, bepoch):
+- """
+- Wrapper for ERFA function ``eraFk45z``.
+-
+- Parameters
+- ----------
+- r1950 : double array
+- d1950 : double array
+- bepoch : double array
+-
+- Returns
+- -------
+- r2000 : double array
+- d2000 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 4 5 z
+- - - - - - - - - -
+-
+- Convert a B1950.0 FK4 star position to J2000.0 FK5, assuming zero
+- proper motion in the FK5 system.
+-
+- This function converts a star's catalog data from the old FK4
+- (Bessel-Newcomb) system to the later IAU 1976 FK5 (Fricke) system,
+- in such a way that the FK5 proper motion is zero. Because such a
+- star has, in general, a non-zero proper motion in the FK4 system,
+- the routine requires the epoch at which the position in the FK4
+- system was determined.
+-
+- Given:
+- r1950,d1950 double B1950.0 FK4 RA,Dec at epoch (rad)
+- bepoch double Besselian epoch (e.g. 1979.3D0)
+-
+- Returned:
+- r2000,d2000 double J2000.0 FK5 RA,Dec (rad)
+-
+- Notes:
+-
+- 1) The epoch bepoch is strictly speaking Besselian, but if a
+- Julian epoch is supplied the result will be affected only to a
+- negligible extent.
+-
+- 2) The method is from Appendix 2 of Aoki et al. (1983), but using
+- the constants of Seidelmann (1992). See the routine eraFk425
+- for a general introduction to the FK4 to FK5 conversion.
+-
+- 3) Conversion from equinox B1950.0 FK4 to equinox J2000.0 FK5 only
+- is provided for. Conversions for different starting and/or
+- ending epochs would require additional treatment for precession,
+- proper motion and E-terms.
+-
+- 4) In the FK4 catalog the proper motions of stars within 10 degrees
+- of the poles do not embody differential E-terms effects and
+- should, strictly speaking, be handled in a different manner from
+- stars outside these regions. However, given the general lack of
+- homogeneity of the star data available for routine astrometry,
+- the difficulties of handling positions that may have been
+- determined from astrometric fields spanning the polar and non-
+- polar regions, the likelihood that the differential E-terms
+- effect was not taken into account when allowing for proper motion
+- in past astrometry, and the undesirability of a discontinuity in
+- the algorithm, the decision has been made in this ERFA algorithm
+- to include the effects of differential E-terms on the proper
+- motions for all stars, whether polar or not. At epoch 2000.0,
+- and measuring "on the sky" rather than in terms of RA change, the
+- errors resulting from this simplification are less than
+- 1 milliarcsecond in position and 1 milliarcsecond per century in
+- proper motion.
+-
+- References:
+-
+- Aoki, S. et al., 1983, "Conversion matrix of epoch B1950.0
+- FK4-based positions of stars to epoch J2000.0 positions in
+- accordance with the new IAU resolutions". Astron.Astrophys.
+- 128, 263-267.
+-
+- Seidelmann, P.K. (ed), 1992, "Explanatory Supplement to the
+- Astronomical Almanac", ISBN 0-935702-68-7.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraC2s p-vector to spherical
+- eraEpb2jd Besselian epoch to Julian date
+- eraEpj Julian date to Julian epoch
+- eraPdp scalar product of two p-vectors
+- eraPmp p-vector minus p-vector
+- eraPpsp p-vector plus scaled p-vector
+- eraPvu update a pv-vector
+- eraS2c spherical to p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r2000, d2000 = ufunc.fk45z(r1950, d1950, bepoch)
+- return r2000, d2000
+-
+-
+-def fk524(r2000, d2000, dr2000, dd2000, p2000, v2000):
+- """
+- Wrapper for ERFA function ``eraFk524``.
+-
+- Parameters
+- ----------
+- r2000 : double array
+- d2000 : double array
+- dr2000 : double array
+- dd2000 : double array
+- p2000 : double array
+- v2000 : double array
+-
+- Returns
+- -------
+- r1950 : double array
+- d1950 : double array
+- dr1950 : double array
+- dd1950 : double array
+- p1950 : double array
+- v1950 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 5 2 4
+- - - - - - - - - -
+-
+- Convert J2000.0 FK5 star catalog data to B1950.0 FK4.
+-
+- Given: (all J2000.0, FK5)
+- r2000,d2000 double J2000.0 RA,Dec (rad)
+- dr2000,dd2000 double J2000.0 proper motions (rad/Jul.yr)
+- p2000 double parallax (arcsec)
+- v2000 double radial velocity (km/s, +ve = moving away)
+-
+- Returned: (all B1950.0, FK4)
+- r1950,d1950 double B1950.0 RA,Dec (rad)
+- dr1950,dd1950 double B1950.0 proper motions (rad/trop.yr)
+- p1950 double parallax (arcsec)
+- v1950 double radial velocity (km/s, +ve = moving away)
+-
+- Notes:
+-
+- 1) The proper motions in RA are dRA/dt rather than cos(Dec)*dRA/dt,
+- and are per year rather than per century.
+-
+- 2) The conversion is somewhat complicated, for several reasons:
+-
+- . Change of standard epoch from J2000.0 to B1950.0.
+-
+- . An intermediate transition date of 1984 January 1.0 TT.
+-
+- . A change of precession model.
+-
+- . Change of time unit for proper motion (Julian to tropical).
+-
+- . FK4 positions include the E-terms of aberration, to simplify
+- the hand computation of annual aberration. FK5 positions
+- assume a rigorous aberration computation based on the Earth's
+- barycentric velocity.
+-
+- . The E-terms also affect proper motions, and in particular cause
+- objects at large distances to exhibit fictitious proper
+- motions.
+-
+- The algorithm is based on Smith et al. (1989) and Yallop et al.
+- (1989), which presented a matrix method due to Standish (1982) as
+- developed by Aoki et al. (1983), using Kinoshita's development of
+- Andoyer's post-Newcomb precession. The numerical constants from
+- Seidelmann (1992) are used canonically.
+-
+- 4) In the FK4 catalog the proper motions of stars within 10 degrees
+- of the poles do not embody differential E-terms effects and
+- should, strictly speaking, be handled in a different manner from
+- stars outside these regions. However, given the general lack of
+- homogeneity of the star data available for routine astrometry,
+- the difficulties of handling positions that may have been
+- determined from astrometric fields spanning the polar and non-
+- polar regions, the likelihood that the differential E-terms
+- effect was not taken into account when allowing for proper motion
+- in past astrometry, and the undesirability of a discontinuity in
+- the algorithm, the decision has been made in this ERFA algorithm
+- to include the effects of differential E-terms on the proper
+- motions for all stars, whether polar or not. At epoch J2000.0,
+- and measuring "on the sky" rather than in terms of RA change, the
+- errors resulting from this simplification are less than
+- 1 milliarcsecond in position and 1 milliarcsecond per century in
+- proper motion.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraPdp scalar product of two p-vectors
+- eraPm modulus of p-vector
+- eraPmp p-vector minus p-vector
+- eraPpp p-vector pluus p-vector
+- eraPv2s pv-vector to spherical coordinates
+- eraS2pv spherical coordinates to pv-vector
+- eraSxp multiply p-vector by scalar
+-
+- References:
+-
+- Aoki, S. et al., 1983, "Conversion matrix of epoch B1950.0
+- FK4-based positions of stars to epoch J2000.0 positions in
+- accordance with the new IAU resolutions". Astron.Astrophys.
+- 128, 263-267.
+-
+- Seidelmann, P.K. (ed), 1992, "Explanatory Supplement to the
+- Astronomical Almanac", ISBN 0-935702-68-7.
+-
+- Smith, C.A. et al., 1989, "The transformation of astrometric
+- catalog systems to the equinox J2000.0". Astron.J. 97, 265.
+-
+- Standish, E.M., 1982, "Conversion of positions and proper motions
+- from B1950.0 to the IAU system at J2000.0". Astron.Astrophys.,
+- 115, 1, 20-22.
+-
+- Yallop, B.D. et al., 1989, "Transformation of mean star places
+- from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space".
+- Astron.J. 97, 274.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r1950, d1950, dr1950, dd1950, p1950, v1950 = ufunc.fk524(r2000, d2000, dr2000, dd2000, p2000, v2000)
+- return r1950, d1950, dr1950, dd1950, p1950, v1950
+-
+-
+-def fk52h(r5, d5, dr5, dd5, px5, rv5):
+- """
+- Wrapper for ERFA function ``eraFk52h``.
+-
+- Parameters
+- ----------
+- r5 : double array
+- d5 : double array
+- dr5 : double array
+- dd5 : double array
+- px5 : double array
+- rv5 : double array
+-
+- Returns
+- -------
+- rh : double array
+- dh : double array
+- drh : double array
+- ddh : double array
+- pxh : double array
+- rvh : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 5 2 h
+- - - - - - - - - -
+-
+- Transform FK5 (J2000.0) star data into the Hipparcos system.
+-
+- Given (all FK5, equinox J2000.0, epoch J2000.0):
+- r5 double RA (radians)
+- d5 double Dec (radians)
+- dr5 double proper motion in RA (dRA/dt, rad/Jyear)
+- dd5 double proper motion in Dec (dDec/dt, rad/Jyear)
+- px5 double parallax (arcsec)
+- rv5 double radial velocity (km/s, positive = receding)
+-
+- Returned (all Hipparcos, epoch J2000.0):
+- rh double RA (radians)
+- dh double Dec (radians)
+- drh double proper motion in RA (dRA/dt, rad/Jyear)
+- ddh double proper motion in Dec (dDec/dt, rad/Jyear)
+- pxh double parallax (arcsec)
+- rvh double radial velocity (km/s, positive = receding)
+-
+- Notes:
+-
+- 1) This function transforms FK5 star positions and proper motions
+- into the system of the Hipparcos catalog.
+-
+- 2) The proper motions in RA are dRA/dt rather than
+- cos(Dec)*dRA/dt, and are per year rather than per century.
+-
+- 3) The FK5 to Hipparcos transformation is modeled as a pure
+- rotation and spin; zonal errors in the FK5 catalog are not
+- taken into account.
+-
+- 4) See also eraH2fk5, eraFk5hz, eraHfk5z.
+-
+- Called:
+- eraStarpv star catalog data to space motion pv-vector
+- eraFk5hip FK5 to Hipparcos rotation and spin
+- eraRxp product of r-matrix and p-vector
+- eraPxp vector product of two p-vectors
+- eraPpp p-vector plus p-vector
+- eraPvstar space motion pv-vector to star catalog data
+-
+- Reference:
+-
+- F.Mignard & M.Froeschle, Astron.Astrophys., 354, 732-739 (2000).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rh, dh, drh, ddh, pxh, rvh = ufunc.fk52h(r5, d5, dr5, dd5, px5, rv5)
+- return rh, dh, drh, ddh, pxh, rvh
+-
+-
+-def fk54z(r2000, d2000, bepoch):
+- """
+- Wrapper for ERFA function ``eraFk54z``.
+-
+- Parameters
+- ----------
+- r2000 : double array
+- d2000 : double array
+- bepoch : double array
+-
+- Returns
+- -------
+- r1950 : double array
+- d1950 : double array
+- dr1950 : double array
+- dd1950 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 5 4 z
+- - - - - - - - - -
+-
+- Convert a J2000.0 FK5 star position to B1950.0 FK4, assuming zero
+- proper motion in FK5 and parallax.
+-
+- Given:
+- r2000,d2000 double J2000.0 FK5 RA,Dec (rad)
+- bepoch double Besselian epoch (e.g. 1950.0)
+-
+- Returned:
+- r1950,d1950 double B1950.0 FK4 RA,Dec (rad) at epoch BEPOCH
+- dr1950,dd1950 double B1950.0 FK4 proper motions (rad/trop.yr)
+-
+- Notes:
+-
+- 1) In contrast to the eraFk524 routine, here the FK5 proper
+- motions, the parallax and the radial velocity are presumed zero.
+-
+- 2) This function converts a star position from the IAU 1976 FK5
+- (Fricke) system to the former FK4 (Bessel-Newcomb) system, for
+- cases such as distant radio sources where it is presumed there is
+- zero parallax and no proper motion. Because of the E-terms of
+- aberration, such objects have (in general) non-zero proper motion
+- in FK4, and the present routine returns those fictitious proper
+- motions.
+-
+- 3) Conversion from B1950.0 FK4 to J2000.0 FK5 only is provided for.
+- Conversions involving other equinoxes would require additional
+- treatment for precession.
+-
+- 4) The position returned by this routine is in the B1950.0 FK4
+- reference system but at Besselian epoch BEPOCH. For comparison
+- with catalogs the BEPOCH argument will frequently be 1950.0. (In
+- this context the distinction between Besselian and Julian epoch
+- is insignificant.)
+-
+- 5) The RA component of the returned (fictitious) proper motion is
+- dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraC2s p-vector to spherical
+- eraFk524 FK4 to FK5
+- eraS2c spherical to p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r1950, d1950, dr1950, dd1950 = ufunc.fk54z(r2000, d2000, bepoch)
+- return r1950, d1950, dr1950, dd1950
+-
+-
+-def fk5hip():
+- """
+- Wrapper for ERFA function ``eraFk5hip``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- r5h : double array
+- s5h : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a F k 5 h i p
+- - - - - - - - - - -
+-
+- FK5 to Hipparcos rotation and spin.
+-
+- Returned:
+- r5h double[3][3] r-matrix: FK5 rotation wrt Hipparcos (Note 2)
+- s5h double[3] r-vector: FK5 spin wrt Hipparcos (Note 3)
+-
+- Notes:
+-
+- 1) This function models the FK5 to Hipparcos transformation as a
+- pure rotation and spin; zonal errors in the FK5 catalogue are
+- not taken into account.
+-
+- 2) The r-matrix r5h operates in the sense:
+-
+- P_Hipparcos = r5h x P_FK5
+-
+- where P_FK5 is a p-vector in the FK5 frame, and P_Hipparcos is
+- the equivalent Hipparcos p-vector.
+-
+- 3) The r-vector s5h represents the time derivative of the FK5 to
+- Hipparcos rotation. The units are radians per year (Julian,
+- TDB).
+-
+- Called:
+- eraRv2m r-vector to r-matrix
+-
+- Reference:
+-
+- F.Mignard & M.Froeschle, Astron.Astrophys., 354, 732-739 (2000).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r5h, s5h = ufunc.fk5hip()
+- return r5h, s5h
+-
+-
+-def fk5hz(r5, d5, date1, date2):
+- """
+- Wrapper for ERFA function ``eraFk5hz``.
+-
+- Parameters
+- ----------
+- r5 : double array
+- d5 : double array
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rh : double array
+- dh : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a F k 5 h z
+- - - - - - - - - -
+-
+- Transform an FK5 (J2000.0) star position into the system of the
+- Hipparcos catalogue, assuming zero Hipparcos proper motion.
+-
+- Given:
+- r5 double FK5 RA (radians), equinox J2000.0, at date
+- d5 double FK5 Dec (radians), equinox J2000.0, at date
+- date1,date2 double TDB date (Notes 1,2)
+-
+- Returned:
+- rh double Hipparcos RA (radians)
+- dh double Hipparcos Dec (radians)
+-
+- Notes:
+-
+- 1) This function converts a star position from the FK5 system to
+- the Hipparcos system, in such a way that the Hipparcos proper
+- motion is zero. Because such a star has, in general, a non-zero
+- proper motion in the FK5 system, the function requires the date
+- at which the position in the FK5 system was determined.
+-
+- 2) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 3) The FK5 to Hipparcos transformation is modeled as a pure
+- rotation and spin; zonal errors in the FK5 catalogue are not
+- taken into account.
+-
+- 4) The position returned by this function is in the Hipparcos
+- reference system but at date date1+date2.
+-
+- 5) See also eraFk52h, eraH2fk5, eraHfk5z.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraFk5hip FK5 to Hipparcos rotation and spin
+- eraSxp multiply p-vector by scalar
+- eraRv2m r-vector to r-matrix
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraPxp vector product of two p-vectors
+- eraC2s p-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Reference:
+-
+- F.Mignard & M.Froeschle, 2000, Astron.Astrophys. 354, 732-739.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rh, dh = ufunc.fk5hz(r5, d5, date1, date2)
+- return rh, dh
+-
+-
+-def h2fk5(rh, dh, drh, ddh, pxh, rvh):
+- """
+- Wrapper for ERFA function ``eraH2fk5``.
+-
+- Parameters
+- ----------
+- rh : double array
+- dh : double array
+- drh : double array
+- ddh : double array
+- pxh : double array
+- rvh : double array
+-
+- Returns
+- -------
+- r5 : double array
+- d5 : double array
+- dr5 : double array
+- dd5 : double array
+- px5 : double array
+- rv5 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a H 2 f k 5
+- - - - - - - - - -
+-
+- Transform Hipparcos star data into the FK5 (J2000.0) system.
+-
+- Given (all Hipparcos, epoch J2000.0):
+- rh double RA (radians)
+- dh double Dec (radians)
+- drh double proper motion in RA (dRA/dt, rad/Jyear)
+- ddh double proper motion in Dec (dDec/dt, rad/Jyear)
+- pxh double parallax (arcsec)
+- rvh double radial velocity (km/s, positive = receding)
+-
+- Returned (all FK5, equinox J2000.0, epoch J2000.0):
+- r5 double RA (radians)
+- d5 double Dec (radians)
+- dr5 double proper motion in RA (dRA/dt, rad/Jyear)
+- dd5 double proper motion in Dec (dDec/dt, rad/Jyear)
+- px5 double parallax (arcsec)
+- rv5 double radial velocity (km/s, positive = receding)
+-
+- Notes:
+-
+- 1) This function transforms Hipparcos star positions and proper
+- motions into FK5 J2000.0.
+-
+- 2) The proper motions in RA are dRA/dt rather than
+- cos(Dec)*dRA/dt, and are per year rather than per century.
+-
+- 3) The FK5 to Hipparcos transformation is modeled as a pure
+- rotation and spin; zonal errors in the FK5 catalog are not
+- taken into account.
+-
+- 4) See also eraFk52h, eraFk5hz, eraHfk5z.
+-
+- Called:
+- eraStarpv star catalog data to space motion pv-vector
+- eraFk5hip FK5 to Hipparcos rotation and spin
+- eraRv2m r-vector to r-matrix
+- eraRxp product of r-matrix and p-vector
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraPxp vector product of two p-vectors
+- eraPmp p-vector minus p-vector
+- eraPvstar space motion pv-vector to star catalog data
+-
+- Reference:
+-
+- F.Mignard & M.Froeschle, Astron.Astrophys., 354, 732-739 (2000).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r5, d5, dr5, dd5, px5, rv5 = ufunc.h2fk5(rh, dh, drh, ddh, pxh, rvh)
+- return r5, d5, dr5, dd5, px5, rv5
+-
+-
+-def hfk5z(rh, dh, date1, date2):
+- """
+- Wrapper for ERFA function ``eraHfk5z``.
+-
+- Parameters
+- ----------
+- rh : double array
+- dh : double array
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- r5 : double array
+- d5 : double array
+- dr5 : double array
+- dd5 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a H f k 5 z
+- - - - - - - - - -
+-
+- Transform a Hipparcos star position into FK5 J2000.0, assuming
+- zero Hipparcos proper motion.
+-
+- Given:
+- rh double Hipparcos RA (radians)
+- dh double Hipparcos Dec (radians)
+- date1,date2 double TDB date (Note 1)
+-
+- Returned (all FK5, equinox J2000.0, date date1+date2):
+- r5 double RA (radians)
+- d5 double Dec (radians)
+- dr5 double FK5 RA proper motion (rad/year, Note 4)
+- dd5 double Dec proper motion (rad/year, Note 4)
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) The proper motion in RA is dRA/dt rather than cos(Dec)*dRA/dt.
+-
+- 3) The FK5 to Hipparcos transformation is modeled as a pure rotation
+- and spin; zonal errors in the FK5 catalogue are not taken into
+- account.
+-
+- 4) It was the intention that Hipparcos should be a close
+- approximation to an inertial frame, so that distant objects have
+- zero proper motion; such objects have (in general) non-zero
+- proper motion in FK5, and this function returns those fictitious
+- proper motions.
+-
+- 5) The position returned by this function is in the FK5 J2000.0
+- reference system but at date date1+date2.
+-
+- 6) See also eraFk52h, eraH2fk5, eraFk5zhz.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraFk5hip FK5 to Hipparcos rotation and spin
+- eraRxp product of r-matrix and p-vector
+- eraSxp multiply p-vector by scalar
+- eraRxr product of two r-matrices
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraPxp vector product of two p-vectors
+- eraPv2s pv-vector to spherical
+- eraAnp normalize angle into range 0 to 2pi
+-
+- Reference:
+-
+- F.Mignard & M.Froeschle, 2000, Astron.Astrophys. 354, 732-739.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r5, d5, dr5, dd5 = ufunc.hfk5z(rh, dh, date1, date2)
+- return r5, d5, dr5, dd5
+-
+-
+-def starpm(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b):
+- """
+- Wrapper for ERFA function ``eraStarpm``.
+-
+- Parameters
+- ----------
+- ra1 : double array
+- dec1 : double array
+- pmr1 : double array
+- pmd1 : double array
+- px1 : double array
+- rv1 : double array
+- ep1a : double array
+- ep1b : double array
+- ep2a : double array
+- ep2b : double array
+-
+- Returns
+- -------
+- ra2 : double array
+- dec2 : double array
+- pmr2 : double array
+- pmd2 : double array
+- px2 : double array
+- rv2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a S t a r p m
+- - - - - - - - - - -
+-
+- Star proper motion: update star catalog data for space motion.
+-
+- Given:
+- ra1 double right ascension (radians), before
+- dec1 double declination (radians), before
+- pmr1 double RA proper motion (radians/year), before
+- pmd1 double Dec proper motion (radians/year), before
+- px1 double parallax (arcseconds), before
+- rv1 double radial velocity (km/s, +ve = receding), before
+- ep1a double "before" epoch, part A (Note 1)
+- ep1b double "before" epoch, part B (Note 1)
+- ep2a double "after" epoch, part A (Note 1)
+- ep2b double "after" epoch, part B (Note 1)
+-
+- Returned:
+- ra2 double right ascension (radians), after
+- dec2 double declination (radians), after
+- pmr2 double RA proper motion (radians/year), after
+- pmd2 double Dec proper motion (radians/year), after
+- px2 double parallax (arcseconds), after
+- rv2 double radial velocity (km/s, +ve = receding), after
+-
+- Returned (function value):
+- int status:
+- -1 = system error (should not occur)
+- 0 = no warnings or errors
+- 1 = distance overridden (Note 6)
+- 2 = excessive velocity (Note 7)
+- 4 = solution didn't converge (Note 8)
+- else = binary logical OR of the above warnings
+-
+- Notes:
+-
+- 1) The starting and ending TDB dates ep1a+ep1b and ep2a+ep2b are
+- Julian Dates, apportioned in any convenient way between the two
+- parts (A and B). For example, JD(TDB)=2450123.7 could be
+- expressed in any of these ways, among others:
+-
+- epna epnb
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) In accordance with normal star-catalog conventions, the object's
+- right ascension and declination are freed from the effects of
+- secular aberration. The frame, which is aligned to the catalog
+- equator and equinox, is Lorentzian and centered on the SSB.
+-
+- The proper motions are the rate of change of the right ascension
+- and declination at the catalog epoch and are in radians per TDB
+- Julian year.
+-
+- The parallax and radial velocity are in the same frame.
+-
+- 3) Care is needed with units. The star coordinates are in radians
+- and the proper motions in radians per Julian year, but the
+- parallax is in arcseconds.
+-
+- 4) The RA proper motion is in terms of coordinate angle, not true
+- angle. If the catalog uses arcseconds for both RA and Dec proper
+- motions, the RA proper motion will need to be divided by cos(Dec)
+- before use.
+-
+- 5) Straight-line motion at constant speed, in the inertial frame,
+- is assumed.
+-
+- 6) An extremely small (or zero or negative) parallax is interpreted
+- to mean that the object is on the "celestial sphere", the radius
+- of which is an arbitrary (large) value (see the eraStarpv
+- function for the value used). When the distance is overridden in
+- this way, the status, initially zero, has 1 added to it.
+-
+- 7) If the space velocity is a significant fraction of c (see the
+- constant VMAX in the function eraStarpv), it is arbitrarily set
+- to zero. When this action occurs, 2 is added to the status.
+-
+- 8) The relativistic adjustment carried out in the eraStarpv function
+- involves an iterative calculation. If the process fails to
+- converge within a set number of iterations, 4 is added to the
+- status.
+-
+- Called:
+- eraStarpv star catalog data to space motion pv-vector
+- eraPvu update a pv-vector
+- eraPdp scalar product of two p-vectors
+- eraPvstar space motion pv-vector to star catalog data
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ra2, dec2, pmr2, pmd2, px2, rv2, c_retval = ufunc.starpm(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b)
+- check_errwarn(c_retval, 'starpm')
+- return ra2, dec2, pmr2, pmd2, px2, rv2
+-
+-
+-STATUS_CODES['starpm'] = {-1: 'system error (should not occur)', 0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above warnings'}
+-
+-
+-def eceq06(date1, date2, dl, db):
+- """
+- Wrapper for ERFA function ``eraEceq06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- dl : double array
+- db : double array
+-
+- Returns
+- -------
+- dr : double array
+- dd : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E c e q 0 6
+- - - - - - - - - - -
+-
+- Transformation from ecliptic coordinates (mean equinox and ecliptic
+- of date) to ICRS RA,Dec, using the IAU 2006 precession model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian date (Note 1)
+- dl,db double ecliptic longitude and latitude (radians)
+-
+- Returned:
+- dr,dd double ICRS right ascension and declination (radians)
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) No assumptions are made about whether the coordinates represent
+- starlight and embody astrometric effects such as parallax or
+- aberration.
+-
+- 3) The transformation is approximately that from ecliptic longitude
+- and latitude (mean equinox and ecliptic of date) to mean J2000.0
+- right ascension and declination, with only frame bias (always
+- less than 25 mas) to disturb this classical picture.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraEcm06 J2000.0 to ecliptic rotation matrix, IAU 2006
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraC2s unit vector to spherical coordinates
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dr, dd = ufunc.eceq06(date1, date2, dl, db)
+- return dr, dd
+-
+-
+-def ecm06(date1, date2):
+- """
+- Wrapper for ERFA function ``eraEcm06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+-
+- Returns
+- -------
+- rm : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E c m 0 6
+- - - - - - - - - -
+-
+- ICRS equatorial to ecliptic rotation matrix, IAU 2006.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian date (Note 1)
+-
+- Returned:
+- rm double[3][3] ICRS to ecliptic rotation matrix
+-
+- Notes:
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 1) The matrix is in the sense
+-
+- E_ep = rm x P_ICRS,
+-
+- where P_ICRS is a vector with respect to ICRS right ascension
+- and declination axes and E_ep is the same vector with respect to
+- the (inertial) ecliptic and equinox of date.
+-
+- 2) P_ICRS is a free vector, merely a direction, typically of unit
+- magnitude, and not bound to any particular spatial origin, such
+- as the Earth, Sun or SSB. No assumptions are made about whether
+- it represents starlight and embodies astrometric effects such as
+- parallax or aberration. The transformation is approximately that
+- between mean J2000.0 right ascension and declination and ecliptic
+- longitude and latitude, with only frame bias (always less than
+- 25 mas) to disturb this classical picture.
+-
+- Called:
+- eraObl06 mean obliquity, IAU 2006
+- eraPmat06 PB matrix, IAU 2006
+- eraIr initialize r-matrix to identity
+- eraRx rotate around X-axis
+- eraRxr product of two r-matrices
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rm = ufunc.ecm06(date1, date2)
+- return rm
+-
+-
+-def eqec06(date1, date2, dr, dd):
+- """
+- Wrapper for ERFA function ``eraEqec06``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- dr : double array
+- dd : double array
+-
+- Returns
+- -------
+- dl : double array
+- db : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a E q e c 0 6
+- - - - - - - - - - -
+-
+- Transformation from ICRS equatorial coordinates to ecliptic
+- coordinates (mean equinox and ecliptic of date) using IAU 2006
+- precession model.
+-
+- Given:
+- date1,date2 double TT as a 2-part Julian date (Note 1)
+- dr,dd double ICRS right ascension and declination (radians)
+-
+- Returned:
+- dl,db double ecliptic longitude and latitude (radians)
+-
+- 1) The TT date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- 2) No assumptions are made about whether the coordinates represent
+- starlight and embody astrometric effects such as parallax or
+- aberration.
+-
+- 3) The transformation is approximately that from mean J2000.0 right
+- ascension and declination to ecliptic longitude and latitude
+- (mean equinox and ecliptic of date), with only frame bias (always
+- less than 25 mas) to disturb this classical picture.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraEcm06 J2000.0 to ecliptic rotation matrix, IAU 2006
+- eraRxp product of r-matrix and p-vector
+- eraC2s unit vector to spherical coordinates
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dl, db = ufunc.eqec06(date1, date2, dr, dd)
+- return dl, db
+-
+-
+-def lteceq(epj, dl, db):
+- """
+- Wrapper for ERFA function ``eraLteceq``.
+-
+- Parameters
+- ----------
+- epj : double array
+- dl : double array
+- db : double array
+-
+- Returns
+- -------
+- dr : double array
+- dd : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a L t e c e q
+- - - - - - - - - - -
+-
+- Transformation from ecliptic coordinates (mean equinox and ecliptic
+- of date) to ICRS RA,Dec, using a long-term precession model.
+-
+- Given:
+- epj double Julian epoch (TT)
+- dl,db double ecliptic longitude and latitude (radians)
+-
+- Returned:
+- dr,dd double ICRS right ascension and declination (radians)
+-
+- 1) No assumptions are made about whether the coordinates represent
+- starlight and embody astrometric effects such as parallax or
+- aberration.
+-
+- 2) The transformation is approximately that from ecliptic longitude
+- and latitude (mean equinox and ecliptic of date) to mean J2000.0
+- right ascension and declination, with only frame bias (always
+- less than 25 mas) to disturb this classical picture.
+-
+- 3) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraLtecm J2000.0 to ecliptic rotation matrix, long term
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraC2s unit vector to spherical coordinates
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dr, dd = ufunc.lteceq(epj, dl, db)
+- return dr, dd
+-
+-
+-def ltecm(epj):
+- """
+- Wrapper for ERFA function ``eraLtecm``.
+-
+- Parameters
+- ----------
+- epj : double array
+-
+- Returns
+- -------
+- rm : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a L t e c m
+- - - - - - - - - -
+-
+- ICRS equatorial to ecliptic rotation matrix, long-term.
+-
+- Given:
+- epj double Julian epoch (TT)
+-
+- Returned:
+- rm double[3][3] ICRS to ecliptic rotation matrix
+-
+- Notes:
+-
+- 1) The matrix is in the sense
+-
+- E_ep = rm x P_ICRS,
+-
+- where P_ICRS is a vector with respect to ICRS right ascension
+- and declination axes and E_ep is the same vector with respect to
+- the (inertial) ecliptic and equinox of epoch epj.
+-
+- 2) P_ICRS is a free vector, merely a direction, typically of unit
+- magnitude, and not bound to any particular spatial origin, such
+- as the Earth, Sun or SSB. No assumptions are made about whether
+- it represents starlight and embodies astrometric effects such as
+- parallax or aberration. The transformation is approximately that
+- between mean J2000.0 right ascension and declination and ecliptic
+- longitude and latitude, with only frame bias (always less than
+- 25 mas) to disturb this classical picture.
+-
+- 3) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- Called:
+- eraLtpequ equator pole, long term
+- eraLtpecl ecliptic pole, long term
+- eraPxp vector product
+- eraPn normalize vector
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rm = ufunc.ltecm(epj)
+- return rm
+-
+-
+-def lteqec(epj, dr, dd):
+- """
+- Wrapper for ERFA function ``eraLteqec``.
+-
+- Parameters
+- ----------
+- epj : double array
+- dr : double array
+- dd : double array
+-
+- Returns
+- -------
+- dl : double array
+- db : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a L t e q e c
+- - - - - - - - - - -
+-
+- Transformation from ICRS equatorial coordinates to ecliptic
+- coordinates (mean equinox and ecliptic of date) using a long-term
+- precession model.
+-
+- Given:
+- epj double Julian epoch (TT)
+- dr,dd double ICRS right ascension and declination (radians)
+-
+- Returned:
+- dl,db double ecliptic longitude and latitude (radians)
+-
+- 1) No assumptions are made about whether the coordinates represent
+- starlight and embody astrometric effects such as parallax or
+- aberration.
+-
+- 2) The transformation is approximately that from mean J2000.0 right
+- ascension and declination to ecliptic longitude and latitude
+- (mean equinox and ecliptic of date), with only frame bias (always
+- less than 25 mas) to disturb this classical picture.
+-
+- 3) The Vondrak et al. (2011, 2012) 400 millennia precession model
+- agrees with the IAU 2006 precession at J2000.0 and stays within
+- 100 microarcseconds during the 20th and 21st centuries. It is
+- accurate to a few arcseconds throughout the historical period,
+- worsening to a few tenths of a degree at the end of the
+- +/- 200,000 year time span.
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraLtecm J2000.0 to ecliptic rotation matrix, long term
+- eraRxp product of r-matrix and p-vector
+- eraC2s unit vector to spherical coordinates
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+-
+- References:
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2011, New precession
+- expressions, valid for long time intervals, Astron.Astrophys. 534,
+- A22
+-
+- Vondrak, J., Capitaine, N. and Wallace, P., 2012, New precession
+- expressions, valid for long time intervals (Corrigendum),
+- Astron.Astrophys. 541, C1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dl, db = ufunc.lteqec(epj, dr, dd)
+- return dl, db
+-
+-
+-def g2icrs(dl, db):
+- """
+- Wrapper for ERFA function ``eraG2icrs``.
+-
+- Parameters
+- ----------
+- dl : double array
+- db : double array
+-
+- Returns
+- -------
+- dr : double array
+- dd : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G 2 i c r s
+- - - - - - - - - - -
+-
+- Transformation from Galactic Coordinates to ICRS.
+-
+- Given:
+- dl double galactic longitude (radians)
+- db double galactic latitude (radians)
+-
+- Returned:
+- dr double ICRS right ascension (radians)
+- dd double ICRS declination (radians)
+-
+- Notes:
+-
+- 1) The IAU 1958 system of Galactic coordinates was defined with
+- respect to the now obsolete reference system FK4 B1950.0. When
+- interpreting the system in a modern context, several factors have
+- to be taken into account:
+-
+- . The inclusion in FK4 positions of the E-terms of aberration.
+-
+- . The distortion of the FK4 proper motion system by differential
+- Galactic rotation.
+-
+- . The use of the B1950.0 equinox rather than the now-standard
+- J2000.0.
+-
+- . The frame bias between ICRS and the J2000.0 mean place system.
+-
+- The Hipparcos Catalogue (Perryman & ESA 1997) provides a rotation
+- matrix that transforms directly between ICRS and Galactic
+- coordinates with the above factors taken into account. The
+- matrix is derived from three angles, namely the ICRS coordinates
+- of the Galactic pole and the longitude of the ascending node of
+- the galactic equator on the ICRS equator. They are given in
+- degrees to five decimal places and for canonical purposes are
+- regarded as exact. In the Hipparcos Catalogue the matrix
+- elements are given to 10 decimal places (about 20 microarcsec).
+- In the present ERFA function the matrix elements have been
+- recomputed from the canonical three angles and are given to 30
+- decimal places.
+-
+- 2) The inverse transformation is performed by the function eraIcrs2g.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+- eraS2c spherical coordinates to unit vector
+- eraTrxp product of transpose of r-matrix and p-vector
+- eraC2s p-vector to spherical
+-
+- Reference:
+- Perryman M.A.C. & ESA, 1997, ESA SP-1200, The Hipparcos and Tycho
+- catalogues. Astrometric and photometric star catalogues
+- derived from the ESA Hipparcos Space Astrometry Mission. ESA
+- Publications Division, Noordwijk, Netherlands.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dr, dd = ufunc.g2icrs(dl, db)
+- return dr, dd
+-
+-
+-def icrs2g(dr, dd):
+- """
+- Wrapper for ERFA function ``eraIcrs2g``.
+-
+- Parameters
+- ----------
+- dr : double array
+- dd : double array
+-
+- Returns
+- -------
+- dl : double array
+- db : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a I c r s 2 g
+- - - - - - - - - - -
+-
+- Transformation from ICRS to Galactic Coordinates.
+-
+- Given:
+- dr double ICRS right ascension (radians)
+- dd double ICRS declination (radians)
+-
+- Returned:
+- dl double galactic longitude (radians)
+- db double galactic latitude (radians)
+-
+- Notes:
+-
+- 1) The IAU 1958 system of Galactic coordinates was defined with
+- respect to the now obsolete reference system FK4 B1950.0. When
+- interpreting the system in a modern context, several factors have
+- to be taken into account:
+-
+- . The inclusion in FK4 positions of the E-terms of aberration.
+-
+- . The distortion of the FK4 proper motion system by differential
+- Galactic rotation.
+-
+- . The use of the B1950.0 equinox rather than the now-standard
+- J2000.0.
+-
+- . The frame bias between ICRS and the J2000.0 mean place system.
+-
+- The Hipparcos Catalogue (Perryman & ESA 1997) provides a rotation
+- matrix that transforms directly between ICRS and Galactic
+- coordinates with the above factors taken into account. The
+- matrix is derived from three angles, namely the ICRS coordinates
+- of the Galactic pole and the longitude of the ascending node of
+- the galactic equator on the ICRS equator. They are given in
+- degrees to five decimal places and for canonical purposes are
+- regarded as exact. In the Hipparcos Catalogue the matrix
+- elements are given to 10 decimal places (about 20 microarcsec).
+- In the present ERFA function the matrix elements have been
+- recomputed from the canonical three angles and are given to 30
+- decimal places.
+-
+- 2) The inverse transformation is performed by the function eraG2icrs.
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+- eraAnpm normalize angle into range +/- pi
+- eraS2c spherical coordinates to unit vector
+- eraRxp product of r-matrix and p-vector
+- eraC2s p-vector to spherical
+-
+- Reference:
+- Perryman M.A.C. & ESA, 1997, ESA SP-1200, The Hipparcos and Tycho
+- catalogues. Astrometric and photometric star catalogues
+- derived from the ESA Hipparcos Space Astrometry Mission. ESA
+- Publications Division, Noordwijk, Netherlands.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- dl, db = ufunc.icrs2g(dr, dd)
+- return dl, db
+-
+-
+-def eform(n):
+- """
+- Wrapper for ERFA function ``eraEform``.
+-
+- Parameters
+- ----------
+- n : int array
+-
+- Returns
+- -------
+- a : double array
+- f : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a E f o r m
+- - - - - - - - - -
+-
+- Earth reference ellipsoids.
+-
+- Given:
+- n int ellipsoid identifier (Note 1)
+-
+- Returned:
+- a double equatorial radius (meters, Note 2)
+- f double flattening (Note 2)
+-
+- Returned (function value):
+- int status: 0 = OK
+- -1 = illegal identifier (Note 3)
+-
+- Notes:
+-
+- 1) The identifier n is a number that specifies the choice of
+- reference ellipsoid. The following are supported:
+-
+- n ellipsoid
+-
+- 1 ERFA_WGS84
+- 2 ERFA_GRS80
+- 3 ERFA_WGS72
+-
+- The n value has no significance outside the ERFA software. For
+- convenience, symbols ERFA_WGS84 etc. are defined in erfam.h.
+-
+- 2) The ellipsoid parameters are returned in the form of equatorial
+- radius in meters (a) and flattening (f). The latter is a number
+- around 0.00335, i.e. around 1/298.
+-
+- 3) For the case where an unsupported n value is supplied, zero a and
+- f are returned, as well as error status.
+-
+- References:
+-
+- Department of Defense World Geodetic System 1984, National
+- Imagery and Mapping Agency Technical Report 8350.2, Third
+- Edition, p3-2.
+-
+- Moritz, H., Bull. Geodesique 66-2, 187 (1992).
+-
+- The Department of Defense World Geodetic System 1972, World
+- Geodetic System Committee, May 1974.
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- p220.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- a, f, c_retval = ufunc.eform(n)
+- check_errwarn(c_retval, 'eform')
+- return a, f
+-
+-
+-STATUS_CODES['eform'] = {0: 'OK', -1: 'illegal identifier (Note 3)'}
+-
+-
+-def gc2gd(n, xyz):
+- """
+- Wrapper for ERFA function ``eraGc2gd``.
+-
+- Parameters
+- ----------
+- n : int array
+- xyz : double array
+-
+- Returns
+- -------
+- elong : double array
+- phi : double array
+- height : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a G c 2 g d
+- - - - - - - - - -
+-
+- Transform geocentric coordinates to geodetic using the specified
+- reference ellipsoid.
+-
+- Given:
+- n int ellipsoid identifier (Note 1)
+- xyz double[3] geocentric vector (Note 2)
+-
+- Returned:
+- elong double longitude (radians, east +ve, Note 3)
+- phi double latitude (geodetic, radians, Note 3)
+- height double height above ellipsoid (geodetic, Notes 2,3)
+-
+- Returned (function value):
+- int status: 0 = OK
+- -1 = illegal identifier (Note 3)
+- -2 = internal error (Note 3)
+-
+- Notes:
+-
+- 1) The identifier n is a number that specifies the choice of
+- reference ellipsoid. The following are supported:
+-
+- n ellipsoid
+-
+- 1 ERFA_WGS84
+- 2 ERFA_GRS80
+- 3 ERFA_WGS72
+-
+- The n value has no significance outside the ERFA software. For
+- convenience, symbols ERFA_WGS84 etc. are defined in erfam.h.
+-
+- 2) The geocentric vector (xyz, given) and height (height, returned)
+- are in meters.
+-
+- 3) An error status -1 means that the identifier n is illegal. An
+- error status -2 is theoretically impossible. In all error cases,
+- all three results are set to -1e9.
+-
+- 4) The inverse transformation is performed in the function eraGd2gc.
+-
+- Called:
+- eraEform Earth reference ellipsoids
+- eraGc2gde geocentric to geodetic transformation, general
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- elong, phi, height, c_retval = ufunc.gc2gd(n, xyz)
+- check_errwarn(c_retval, 'gc2gd')
+- return elong, phi, height
+-
+-
+-STATUS_CODES['gc2gd'] = {0: 'OK', -1: 'illegal identifier (Note 3)', -2: 'internal error (Note 3)'}
+-
+-
+-def gc2gde(a, f, xyz):
+- """
+- Wrapper for ERFA function ``eraGc2gde``.
+-
+- Parameters
+- ----------
+- a : double array
+- f : double array
+- xyz : double array
+-
+- Returns
+- -------
+- elong : double array
+- phi : double array
+- height : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G c 2 g d e
+- - - - - - - - - - -
+-
+- Transform geocentric coordinates to geodetic for a reference
+- ellipsoid of specified form.
+-
+- Given:
+- a double equatorial radius (Notes 2,4)
+- f double flattening (Note 3)
+- xyz double[3] geocentric vector (Note 4)
+-
+- Returned:
+- elong double longitude (radians, east +ve)
+- phi double latitude (geodetic, radians)
+- height double height above ellipsoid (geodetic, Note 4)
+-
+- Returned (function value):
+- int status: 0 = OK
+- -1 = illegal f
+- -2 = illegal a
+-
+- Notes:
+-
+- 1) This function is based on the GCONV2H Fortran subroutine by
+- Toshio Fukushima (see reference).
+-
+- 2) The equatorial radius, a, can be in any units, but meters is
+- the conventional choice.
+-
+- 3) The flattening, f, is (for the Earth) a value around 0.00335,
+- i.e. around 1/298.
+-
+- 4) The equatorial radius, a, and the geocentric vector, xyz,
+- must be given in the same units, and determine the units of
+- the returned height, height.
+-
+- 5) If an error occurs (status < 0), elong, phi and height are
+- unchanged.
+-
+- 6) The inverse transformation is performed in the function
+- eraGd2gce.
+-
+- 7) The transformation for a standard ellipsoid (such as ERFA_WGS84) can
+- more conveniently be performed by calling eraGc2gd, which uses a
+- numerical code to identify the required A and F values.
+-
+- Reference:
+-
+- Fukushima, T., "Transformation from Cartesian to geodetic
+- coordinates accelerated by Halley's method", J.Geodesy (2006)
+- 79: 689-693
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- elong, phi, height, c_retval = ufunc.gc2gde(a, f, xyz)
+- check_errwarn(c_retval, 'gc2gde')
+- return elong, phi, height
+-
+-
+-STATUS_CODES['gc2gde'] = {0: 'OK', -1: 'illegal f', -2: 'illegal a'}
+-
+-
+-def gd2gc(n, elong, phi, height):
+- """
+- Wrapper for ERFA function ``eraGd2gc``.
+-
+- Parameters
+- ----------
+- n : int array
+- elong : double array
+- phi : double array
+- height : double array
+-
+- Returns
+- -------
+- xyz : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a G d 2 g c
+- - - - - - - - - -
+-
+- Transform geodetic coordinates to geocentric using the specified
+- reference ellipsoid.
+-
+- Given:
+- n int ellipsoid identifier (Note 1)
+- elong double longitude (radians, east +ve)
+- phi double latitude (geodetic, radians, Note 3)
+- height double height above ellipsoid (geodetic, Notes 2,3)
+-
+- Returned:
+- xyz double[3] geocentric vector (Note 2)
+-
+- Returned (function value):
+- int status: 0 = OK
+- -1 = illegal identifier (Note 3)
+- -2 = illegal case (Note 3)
+-
+- Notes:
+-
+- 1) The identifier n is a number that specifies the choice of
+- reference ellipsoid. The following are supported:
+-
+- n ellipsoid
+-
+- 1 ERFA_WGS84
+- 2 ERFA_GRS80
+- 3 ERFA_WGS72
+-
+- The n value has no significance outside the ERFA software. For
+- convenience, symbols ERFA_WGS84 etc. are defined in erfam.h.
+-
+- 2) The height (height, given) and the geocentric vector (xyz,
+- returned) are in meters.
+-
+- 3) No validation is performed on the arguments elong, phi and
+- height. An error status -1 means that the identifier n is
+- illegal. An error status -2 protects against cases that would
+- lead to arithmetic exceptions. In all error cases, xyz is set
+- to zeros.
+-
+- 4) The inverse transformation is performed in the function eraGc2gd.
+-
+- Called:
+- eraEform Earth reference ellipsoids
+- eraGd2gce geodetic to geocentric transformation, general
+- eraZp zero p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- xyz, c_retval = ufunc.gd2gc(n, elong, phi, height)
+- check_errwarn(c_retval, 'gd2gc')
+- return xyz
+-
+-
+-STATUS_CODES['gd2gc'] = {0: 'OK', -1: 'illegal identifier (Note 3)', -2: 'illegal case (Note 3)'}
+-
+-
+-def gd2gce(a, f, elong, phi, height):
+- """
+- Wrapper for ERFA function ``eraGd2gce``.
+-
+- Parameters
+- ----------
+- a : double array
+- f : double array
+- elong : double array
+- phi : double array
+- height : double array
+-
+- Returns
+- -------
+- xyz : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a G d 2 g c e
+- - - - - - - - - - -
+-
+- Transform geodetic coordinates to geocentric for a reference
+- ellipsoid of specified form.
+-
+- Given:
+- a double equatorial radius (Notes 1,4)
+- f double flattening (Notes 2,4)
+- elong double longitude (radians, east +ve)
+- phi double latitude (geodetic, radians, Note 4)
+- height double height above ellipsoid (geodetic, Notes 3,4)
+-
+- Returned:
+- xyz double[3] geocentric vector (Note 3)
+-
+- Returned (function value):
+- int status: 0 = OK
+- -1 = illegal case (Note 4)
+- Notes:
+-
+- 1) The equatorial radius, a, can be in any units, but meters is
+- the conventional choice.
+-
+- 2) The flattening, f, is (for the Earth) a value around 0.00335,
+- i.e. around 1/298.
+-
+- 3) The equatorial radius, a, and the height, height, must be
+- given in the same units, and determine the units of the
+- returned geocentric vector, xyz.
+-
+- 4) No validation is performed on individual arguments. The error
+- status -1 protects against (unrealistic) cases that would lead
+- to arithmetic exceptions. If an error occurs, xyz is unchanged.
+-
+- 5) The inverse transformation is performed in the function
+- eraGc2gde.
+-
+- 6) The transformation for a standard ellipsoid (such as ERFA_WGS84) can
+- more conveniently be performed by calling eraGd2gc, which uses a
+- numerical code to identify the required a and f values.
+-
+- References:
+-
+- Green, R.M., Spherical Astronomy, Cambridge University Press,
+- (1985) Section 4.5, p96.
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992),
+- Section 4.22, p202.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- xyz, c_retval = ufunc.gd2gce(a, f, elong, phi, height)
+- check_errwarn(c_retval, 'gd2gce')
+- return xyz
+-
+-
+-STATUS_CODES['gd2gce'] = {0: 'OK', -1: 'illegal case (Note 4)Notes:'}
+-
+-
+-def d2dtf(scale, ndp, d1, d2):
+- """
+- Wrapper for ERFA function ``eraD2dtf``.
+-
+- Parameters
+- ----------
+- scale : const char array
+- ndp : int array
+- d1 : double array
+- d2 : double array
+-
+- Returns
+- -------
+- iy : int array
+- im : int array
+- id : int array
+- ihmsf : int array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a D 2 d t f
+- - - - - - - - - -
+-
+- Format for output a 2-part Julian Date (or in the case of UTC a
+- quasi-JD form that includes special provision for leap seconds).
+-
+- Given:
+- scale char[] time scale ID (Note 1)
+- ndp int resolution (Note 2)
+- d1,d2 double time as a 2-part Julian Date (Notes 3,4)
+-
+- Returned:
+- iy,im,id int year, month, day in Gregorian calendar (Note 5)
+- ihmsf int[4] hours, minutes, seconds, fraction (Note 1)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 5)
+- 0 = OK
+- -1 = unacceptable date (Note 6)
+-
+- Notes:
+-
+- 1) scale identifies the time scale. Only the value "UTC" (in upper
+- case) is significant, and enables handling of leap seconds (see
+- Note 4).
+-
+- 2) ndp is the number of decimal places in the seconds field, and can
+- have negative as well as positive values, such as:
+-
+- ndp resolution
+- -4 1 00 00
+- -3 0 10 00
+- -2 0 01 00
+- -1 0 00 10
+- 0 0 00 01
+- 1 0 00 00.1
+- 2 0 00 00.01
+- 3 0 00 00.001
+-
+- The limits are platform dependent, but a safe range is -5 to +9.
+-
+- 3) d1+d2 is Julian Date, apportioned in any convenient way between
+- the two arguments, for example where d1 is the Julian Day Number
+- and d2 is the fraction of a day. In the case of UTC, where the
+- use of JD is problematical, special conventions apply: see the
+- next note.
+-
+- 4) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The ERFA internal convention is that
+- the quasi-JD day represents UTC days whether the length is 86399,
+- 86400 or 86401 SI seconds. In the 1960-1972 era there were
+- smaller jumps (in either direction) each time the linear UTC(TAI)
+- expression was changed, and these "mini-leaps" are also included
+- in the ERFA convention.
+-
+- 5) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- 6) For calendar conventions and limitations, see eraCal2jd.
+-
+- Called:
+- eraJd2cal JD to Gregorian calendar
+- eraD2tf decompose days to hms
+- eraDat delta(AT) = TAI-UTC
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- iy, im, id, ihmsf, c_retval = ufunc.d2dtf(scale, ndp, d1, d2)
+- check_errwarn(c_retval, 'd2dtf')
+- return iy, im, id, ihmsf
+-
+-
+-STATUS_CODES['d2dtf'] = {1: 'dubious year (Note 5)', 0: 'OK', -1: 'unacceptable date (Note 6)'}
+-
+-
+-def dat(iy, im, id, fd):
+- """
+- Wrapper for ERFA function ``eraDat``.
+-
+- Parameters
+- ----------
+- iy : int array
+- im : int array
+- id : int array
+- fd : double array
+-
+- Returns
+- -------
+- deltat : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a D a t
+- - - - - - - -
+-
+- For a given UTC date, calculate Delta(AT) = TAI-UTC.
+-
+- :------------------------------------------:
+- : :
+- : IMPORTANT :
+- : :
+- : A new version of this function must be :
+- : produced whenever a new leap second is :
+- : announced. There are four items to :
+- : change on each such occasion: :
+- : :
+- : 1) A new line must be added to the set :
+- : of statements that initialize the :
+- : array "changes". :
+- : :
+- : 2) The constant IYV must be set to the :
+- : current year. :
+- : :
+- : 3) The "Latest leap second" comment :
+- : below must be set to the new leap :
+- : second date. :
+- : :
+- : 4) The "This revision" comment, later, :
+- : must be set to the current date. :
+- : :
+- : Change (2) must also be carried out :
+- : whenever the function is re-issued, :
+- : even if no leap seconds have been :
+- : added. :
+- : :
+- : Latest leap second: 2016 December 31 :
+- : :
+- :__________________________________________:
+-
+- Given:
+- iy int UTC: year (Notes 1 and 2)
+- im int month (Note 2)
+- id int day (Notes 2 and 3)
+- fd double fraction of day (Note 4)
+-
+- Returned:
+- deltat double TAI minus UTC, seconds
+-
+- Returned (function value):
+- int status (Note 5):
+- 1 = dubious year (Note 1)
+- 0 = OK
+- -1 = bad year
+- -2 = bad month
+- -3 = bad day (Note 3)
+- -4 = bad fraction (Note 4)
+- -5 = internal error (Note 5)
+-
+- Notes:
+-
+- 1) UTC began at 1960 January 1.0 (JD 2436934.5) and it is improper
+- to call the function with an earlier date. If this is attempted,
+- zero is returned together with a warning status.
+-
+- Because leap seconds cannot, in principle, be predicted in
+- advance, a reliable check for dates beyond the valid range is
+- impossible. To guard against gross errors, a year five or more
+- after the release year of the present function (see the constant
+- IYV) is considered dubious. In this case a warning status is
+- returned but the result is computed in the normal way.
+-
+- For both too-early and too-late years, the warning status is +1.
+- This is distinct from the error status -1, which signifies a year
+- so early that JD could not be computed.
+-
+- 2) If the specified date is for a day which ends with a leap second,
+- the TAI-UTC value returned is for the period leading up to the
+- leap second. If the date is for a day which begins as a leap
+- second ends, the TAI-UTC returned is for the period following the
+- leap second.
+-
+- 3) The day number must be in the normal calendar range, for example
+- 1 through 30 for April. The "almanac" convention of allowing
+- such dates as January 0 and December 32 is not supported in this
+- function, in order to avoid confusion near leap seconds.
+-
+- 4) The fraction of day is used only for dates before the
+- introduction of leap seconds, the first of which occurred at the
+- end of 1971. It is tested for validity (0 to 1 is the valid
+- range) even if not used; if invalid, zero is used and status -4
+- is returned. For many applications, setting fd to zero is
+- acceptable; the resulting error is always less than 3 ms (and
+- occurs only pre-1972).
+-
+- 5) The status value returned in the case where there are multiple
+- errors refers to the first error detected. For example, if the
+- month and day are 13 and 32 respectively, status -2 (bad month)
+- will be returned. The "internal error" status refers to a
+- case that is impossible but causes some compilers to issue a
+- warning.
+-
+- 6) In cases where a valid result is not available, zero is returned.
+-
+- References:
+-
+- 1) For dates from 1961 January 1 onwards, the expressions from the
+- file ftp://maia.usno.navy.mil/ser7/tai-utc.dat are used.
+-
+- 2) The 5ms timestep at 1961 January 1 is taken from 2.58.1 (p87) of
+- the 1992 Explanatory Supplement.
+-
+- Called:
+- eraCal2jd Gregorian calendar to JD
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- deltat, c_retval = ufunc.dat(iy, im, id, fd)
+- check_errwarn(c_retval, 'dat')
+- return deltat
+-
+-
+-STATUS_CODES['dat'] = {1: 'dubious year (Note 1)', 0: 'OK', -1: 'bad year', -2: 'bad month', -3: 'bad day (Note 3)', -4: 'bad fraction (Note 4)', -5: 'internal error (Note 5)'}
+-
+-
+-def dtdb(date1, date2, ut, elong, u, v):
+- """
+- Wrapper for ERFA function ``eraDtdb``.
+-
+- Parameters
+- ----------
+- date1 : double array
+- date2 : double array
+- ut : double array
+- elong : double array
+- u : double array
+- v : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a D t d b
+- - - - - - - - -
+-
+- An approximation to TDB-TT, the difference between barycentric
+- dynamical time and terrestrial time, for an observer on the Earth.
+-
+- The different time scales - proper, coordinate and realized - are
+- related to each other:
+-
+- TAI <- physically realized
+- :
+- offset <- observed (nominally +32.184s)
+- :
+- TT <- terrestrial time
+- :
+- rate adjustment (L_G) <- definition of TT
+- :
+- TCG <- time scale for GCRS
+- :
+- "periodic" terms <- eraDtdb is an implementation
+- :
+- rate adjustment (L_C) <- function of solar-system ephemeris
+- :
+- TCB <- time scale for BCRS
+- :
+- rate adjustment (-L_B) <- definition of TDB
+- :
+- TDB <- TCB scaled to track TT
+- :
+- "periodic" terms <- -eraDtdb is an approximation
+- :
+- TT <- terrestrial time
+-
+- Adopted values for the various constants can be found in the IERS
+- Conventions (McCarthy & Petit 2003).
+-
+- Given:
+- date1,date2 double date, TDB (Notes 1-3)
+- ut double universal time (UT1, fraction of one day)
+- elong double longitude (east positive, radians)
+- u double distance from Earth spin axis (km)
+- v double distance north of equatorial plane (km)
+-
+- Returned (function value):
+- double TDB-TT (seconds)
+-
+- Notes:
+-
+- 1) The date date1+date2 is a Julian Date, apportioned in any
+- convenient way between the two arguments. For example,
+- JD(TT)=2450123.7 could be expressed in any of these ways,
+- among others:
+-
+- date1 date2
+-
+- 2450123.7 0.0 (JD method)
+- 2451545.0 -1421.3 (J2000 method)
+- 2400000.5 50123.2 (MJD method)
+- 2450123.5 0.2 (date & time method)
+-
+- The JD method is the most natural and convenient to use in
+- cases where the loss of several decimal digits of resolution
+- is acceptable. The J2000 method is best matched to the way
+- the argument is handled internally and will deliver the
+- optimum resolution. The MJD method and the date & time methods
+- are both good compromises between resolution and convenience.
+-
+- Although the date is, formally, barycentric dynamical time (TDB),
+- the terrestrial dynamical time (TT) can be used with no practical
+- effect on the accuracy of the prediction.
+-
+- 2) TT can be regarded as a coordinate time that is realized as an
+- offset of 32.184s from International Atomic Time, TAI. TT is a
+- specific linear transformation of geocentric coordinate time TCG,
+- which is the time scale for the Geocentric Celestial Reference
+- System, GCRS.
+-
+- 3) TDB is a coordinate time, and is a specific linear transformation
+- of barycentric coordinate time TCB, which is the time scale for
+- the Barycentric Celestial Reference System, BCRS.
+-
+- 4) The difference TCG-TCB depends on the masses and positions of the
+- bodies of the solar system and the velocity of the Earth. It is
+- dominated by a rate difference, the residual being of a periodic
+- character. The latter, which is modeled by the present function,
+- comprises a main (annual) sinusoidal term of amplitude
+- approximately 0.00166 seconds, plus planetary terms up to about
+- 20 microseconds, and lunar and diurnal terms up to 2 microseconds.
+- These effects come from the changing transverse Doppler effect
+- and gravitational red-shift as the observer (on the Earth's
+- surface) experiences variations in speed (with respect to the
+- BCRS) and gravitational potential.
+-
+- 5) TDB can be regarded as the same as TCB but with a rate adjustment
+- to keep it close to TT, which is convenient for many applications.
+- The history of successive attempts to define TDB is set out in
+- Resolution 3 adopted by the IAU General Assembly in 2006, which
+- defines a fixed TDB(TCB) transformation that is consistent with
+- contemporary solar-system ephemerides. Future ephemerides will
+- imply slightly changed transformations between TCG and TCB, which
+- could introduce a linear drift between TDB and TT; however, any
+- such drift is unlikely to exceed 1 nanosecond per century.
+-
+- 6) The geocentric TDB-TT model used in the present function is that of
+- Fairhead & Bretagnon (1990), in its full form. It was originally
+- supplied by Fairhead (private communications with P.T.Wallace,
+- 1990) as a Fortran subroutine. The present C function contains an
+- adaptation of the Fairhead code. The numerical results are
+- essentially unaffected by the changes, the differences with
+- respect to the Fairhead & Bretagnon original being at the 1e-20 s
+- level.
+-
+- The topocentric part of the model is from Moyer (1981) and
+- Murray (1983), with fundamental arguments adapted from
+- Simon et al. 1994. It is an approximation to the expression
+- ( v / c ) . ( r / c ), where v is the barycentric velocity of
+- the Earth, r is the geocentric position of the observer and
+- c is the speed of light.
+-
+- By supplying zeroes for u and v, the topocentric part of the
+- model can be nullified, and the function will return the Fairhead
+- & Bretagnon result alone.
+-
+- 7) During the interval 1950-2050, the absolute accuracy is better
+- than +/- 3 nanoseconds relative to time ephemerides obtained by
+- direct numerical integrations based on the JPL DE405 solar system
+- ephemeris.
+-
+- 8) It must be stressed that the present function is merely a model,
+- and that numerical integration of solar-system ephemerides is the
+- definitive method for predicting the relationship between TCG and
+- TCB and hence between TT and TDB.
+-
+- References:
+-
+- Fairhead, L., & Bretagnon, P., Astron.Astrophys., 229, 240-247
+- (1990).
+-
+- IAU 2006 Resolution 3.
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Moyer, T.D., Cel.Mech., 23, 33 (1981).
+-
+- Murray, C.A., Vectorial Astrometry, Adam Hilger (1983).
+-
+- Seidelmann, P.K. et al., Explanatory Supplement to the
+- Astronomical Almanac, Chapter 2, University Science Books (1992).
+-
+- Simon, J.L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
+- Francou, G. & Laskar, J., Astron.Astrophys., 282, 663-683 (1994).
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.dtdb(date1, date2, ut, elong, u, v)
+- return c_retval
+-
+-
+-def dtf2d(scale, iy, im, id, ihr, imn, sec):
+- """
+- Wrapper for ERFA function ``eraDtf2d``.
+-
+- Parameters
+- ----------
+- scale : const char array
+- iy : int array
+- im : int array
+- id : int array
+- ihr : int array
+- imn : int array
+- sec : double array
+-
+- Returns
+- -------
+- d1 : double array
+- d2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a D t f 2 d
+- - - - - - - - - -
+-
+- Encode date and time fields into 2-part Julian Date (or in the case
+- of UTC a quasi-JD form that includes special provision for leap
+- seconds).
+-
+- Given:
+- scale char[] time scale ID (Note 1)
+- iy,im,id int year, month, day in Gregorian calendar (Note 2)
+- ihr,imn int hour, minute
+- sec double seconds
+-
+- Returned:
+- d1,d2 double 2-part Julian Date (Notes 3,4)
+-
+- Returned (function value):
+- int status: +3 = both of next two
+- +2 = time is after end of day (Note 5)
+- +1 = dubious year (Note 6)
+- 0 = OK
+- -1 = bad year
+- -2 = bad month
+- -3 = bad day
+- -4 = bad hour
+- -5 = bad minute
+- -6 = bad second (<0)
+-
+- Notes:
+-
+- 1) scale identifies the time scale. Only the value "UTC" (in upper
+- case) is significant, and enables handling of leap seconds (see
+- Note 4).
+-
+- 2) For calendar conventions and limitations, see eraCal2jd.
+-
+- 3) The sum of the results, d1+d2, is Julian Date, where normally d1
+- is the Julian Day Number and d2 is the fraction of a day. In the
+- case of UTC, where the use of JD is problematical, special
+- conventions apply: see the next note.
+-
+- 4) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The ERFA internal convention is that
+- the quasi-JD day represents UTC days whether the length is 86399,
+- 86400 or 86401 SI seconds. In the 1960-1972 era there were
+- smaller jumps (in either direction) each time the linear UTC(TAI)
+- expression was changed, and these "mini-leaps" are also included
+- in the ERFA convention.
+-
+- 5) The warning status "time is after end of day" usually means that
+- the sec argument is greater than 60.0. However, in a day ending
+- in a leap second the limit changes to 61.0 (or 59.0 in the case
+- of a negative leap second).
+-
+- 6) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- 7) Only in the case of continuous and regular time scales (TAI, TT,
+- TCG, TCB and TDB) is the result d1+d2 a Julian Date, strictly
+- speaking. In the other cases (UT1 and UTC) the result must be
+- used with circumspection; in particular the difference between
+- two such results cannot be interpreted as a precise time
+- interval.
+-
+- Called:
+- eraCal2jd Gregorian calendar to JD
+- eraDat delta(AT) = TAI-UTC
+- eraJd2cal JD to Gregorian calendar
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- d1, d2, c_retval = ufunc.dtf2d(scale, iy, im, id, ihr, imn, sec)
+- check_errwarn(c_retval, 'dtf2d')
+- return d1, d2
+-
+-
+-STATUS_CODES['dtf2d'] = {3: 'both of next two', 2: 'time is after end of day (Note 5)', 1: 'dubious year (Note 6)', 0: 'OK', -1: 'bad year', -2: 'bad month', -3: 'bad day', -4: 'bad hour', -5: 'bad minute', -6: 'bad second (<0)'}
+-
+-
+-def taitt(tai1, tai2):
+- """
+- Wrapper for ERFA function ``eraTaitt``.
+-
+- Parameters
+- ----------
+- tai1 : double array
+- tai2 : double array
+-
+- Returns
+- -------
+- tt1 : double array
+- tt2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T a i t t
+- - - - - - - - - -
+-
+- Time scale transformation: International Atomic Time, TAI, to
+- Terrestrial Time, TT.
+-
+- Given:
+- tai1,tai2 double TAI as a 2-part Julian Date
+-
+- Returned:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Note:
+-
+- tai1+tai2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tai1 is the Julian
+- Day Number and tai2 is the fraction of a day. The returned
+- tt1,tt2 follow suit.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tt1, tt2, c_retval = ufunc.taitt(tai1, tai2)
+- check_errwarn(c_retval, 'taitt')
+- return tt1, tt2
+-
+-
+-STATUS_CODES['taitt'] = {0: 'OK'}
+-
+-
+-def taiut1(tai1, tai2, dta):
+- """
+- Wrapper for ERFA function ``eraTaiut1``.
+-
+- Parameters
+- ----------
+- tai1 : double array
+- tai2 : double array
+- dta : double array
+-
+- Returns
+- -------
+- ut11 : double array
+- ut12 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a T a i u t 1
+- - - - - - - - - - -
+-
+- Time scale transformation: International Atomic Time, TAI, to
+- Universal Time, UT1.
+-
+- Given:
+- tai1,tai2 double TAI as a 2-part Julian Date
+- dta double UT1-TAI in seconds
+-
+- Returned:
+- ut11,ut12 double UT1 as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tai1+tai2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tai1 is the Julian
+- Day Number and tai2 is the fraction of a day. The returned
+- UT11,UT12 follow suit.
+-
+- 2) The argument dta, i.e. UT1-TAI, is an observed quantity, and is
+- available from IERS tabulations.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ut11, ut12, c_retval = ufunc.taiut1(tai1, tai2, dta)
+- check_errwarn(c_retval, 'taiut1')
+- return ut11, ut12
+-
+-
+-STATUS_CODES['taiut1'] = {0: 'OK'}
+-
+-
+-def taiutc(tai1, tai2):
+- """
+- Wrapper for ERFA function ``eraTaiutc``.
+-
+- Parameters
+- ----------
+- tai1 : double array
+- tai2 : double array
+-
+- Returns
+- -------
+- utc1 : double array
+- utc2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a T a i u t c
+- - - - - - - - - - -
+-
+- Time scale transformation: International Atomic Time, TAI, to
+- Coordinated Universal Time, UTC.
+-
+- Given:
+- tai1,tai2 double TAI as a 2-part Julian Date (Note 1)
+-
+- Returned:
+- utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-3)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 4)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) tai1+tai2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tai1 is the Julian
+- Day Number and tai2 is the fraction of a day. The returned utc1
+- and utc2 form an analogous pair, except that a special convention
+- is used, to deal with the problem of leap seconds - see the next
+- note.
+-
+- 2) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The convention in the present
+- function is that the JD day represents UTC days whether the
+- length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era
+- there were smaller jumps (in either direction) each time the
+- linear UTC(TAI) expression was changed, and these "mini-leaps"
+- are also included in the ERFA convention.
+-
+- 3) The function eraD2dtf can be used to transform the UTC quasi-JD
+- into calendar date and clock time, including UTC leap second
+- handling.
+-
+- 4) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- Called:
+- eraUtctai UTC to TAI
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- utc1, utc2, c_retval = ufunc.taiutc(tai1, tai2)
+- check_errwarn(c_retval, 'taiutc')
+- return utc1, utc2
+-
+-
+-STATUS_CODES['taiutc'] = {1: 'dubious year (Note 4)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def tcbtdb(tcb1, tcb2):
+- """
+- Wrapper for ERFA function ``eraTcbtdb``.
+-
+- Parameters
+- ----------
+- tcb1 : double array
+- tcb2 : double array
+-
+- Returns
+- -------
+- tdb1 : double array
+- tdb2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a T c b t d b
+- - - - - - - - - - -
+-
+- Time scale transformation: Barycentric Coordinate Time, TCB, to
+- Barycentric Dynamical Time, TDB.
+-
+- Given:
+- tcb1,tcb2 double TCB as a 2-part Julian Date
+-
+- Returned:
+- tdb1,tdb2 double TDB as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tcb1+tcb2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tcb1 is the Julian
+- Day Number and tcb2 is the fraction of a day. The returned
+- tdb1,tdb2 follow suit.
+-
+- 2) The 2006 IAU General Assembly introduced a conventional linear
+- transformation between TDB and TCB. This transformation
+- compensates for the drift between TCB and terrestrial time TT,
+- and keeps TDB approximately centered on TT. Because the
+- relationship between TT and TCB depends on the adopted solar
+- system ephemeris, the degree of alignment between TDB and TT over
+- long intervals will vary according to which ephemeris is used.
+- Former definitions of TDB attempted to avoid this problem by
+- stipulating that TDB and TT should differ only by periodic
+- effects. This is a good description of the nature of the
+- relationship but eluded precise mathematical formulation. The
+- conventional linear relationship adopted in 2006 sidestepped
+- these difficulties whilst delivering a TDB that in practice was
+- consistent with values before that date.
+-
+- 3) TDB is essentially the same as Teph, the time argument for the
+- JPL solar system ephemerides.
+-
+- Reference:
+-
+- IAU 2006 Resolution B3
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tdb1, tdb2, c_retval = ufunc.tcbtdb(tcb1, tcb2)
+- check_errwarn(c_retval, 'tcbtdb')
+- return tdb1, tdb2
+-
+-
+-STATUS_CODES['tcbtdb'] = {0: 'OK'}
+-
+-
+-def tcgtt(tcg1, tcg2):
+- """
+- Wrapper for ERFA function ``eraTcgtt``.
+-
+- Parameters
+- ----------
+- tcg1 : double array
+- tcg2 : double array
+-
+- Returns
+- -------
+- tt1 : double array
+- tt2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T c g t t
+- - - - - - - - - -
+-
+- Time scale transformation: Geocentric Coordinate Time, TCG, to
+- Terrestrial Time, TT.
+-
+- Given:
+- tcg1,tcg2 double TCG as a 2-part Julian Date
+-
+- Returned:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Note:
+-
+- tcg1+tcg2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tcg1 is the Julian
+- Day Number and tcg22 is the fraction of a day. The returned
+- tt1,tt2 follow suit.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),.
+- IERS Technical Note No. 32, BKG (2004)
+-
+- IAU 2000 Resolution B1.9
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tt1, tt2, c_retval = ufunc.tcgtt(tcg1, tcg2)
+- check_errwarn(c_retval, 'tcgtt')
+- return tt1, tt2
+-
+-
+-STATUS_CODES['tcgtt'] = {0: 'OK'}
+-
+-
+-def tdbtcb(tdb1, tdb2):
+- """
+- Wrapper for ERFA function ``eraTdbtcb``.
+-
+- Parameters
+- ----------
+- tdb1 : double array
+- tdb2 : double array
+-
+- Returns
+- -------
+- tcb1 : double array
+- tcb2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a T d b t c b
+- - - - - - - - - - -
+-
+- Time scale transformation: Barycentric Dynamical Time, TDB, to
+- Barycentric Coordinate Time, TCB.
+-
+- Given:
+- tdb1,tdb2 double TDB as a 2-part Julian Date
+-
+- Returned:
+- tcb1,tcb2 double TCB as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tdb1+tdb2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tdb1 is the Julian
+- Day Number and tdb2 is the fraction of a day. The returned
+- tcb1,tcb2 follow suit.
+-
+- 2) The 2006 IAU General Assembly introduced a conventional linear
+- transformation between TDB and TCB. This transformation
+- compensates for the drift between TCB and terrestrial time TT,
+- and keeps TDB approximately centered on TT. Because the
+- relationship between TT and TCB depends on the adopted solar
+- system ephemeris, the degree of alignment between TDB and TT over
+- long intervals will vary according to which ephemeris is used.
+- Former definitions of TDB attempted to avoid this problem by
+- stipulating that TDB and TT should differ only by periodic
+- effects. This is a good description of the nature of the
+- relationship but eluded precise mathematical formulation. The
+- conventional linear relationship adopted in 2006 sidestepped
+- these difficulties whilst delivering a TDB that in practice was
+- consistent with values before that date.
+-
+- 3) TDB is essentially the same as Teph, the time argument for the
+- JPL solar system ephemerides.
+-
+- Reference:
+-
+- IAU 2006 Resolution B3
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tcb1, tcb2, c_retval = ufunc.tdbtcb(tdb1, tdb2)
+- check_errwarn(c_retval, 'tdbtcb')
+- return tcb1, tcb2
+-
+-
+-STATUS_CODES['tdbtcb'] = {0: 'OK'}
+-
+-
+-def tdbtt(tdb1, tdb2, dtr):
+- """
+- Wrapper for ERFA function ``eraTdbtt``.
+-
+- Parameters
+- ----------
+- tdb1 : double array
+- tdb2 : double array
+- dtr : double array
+-
+- Returns
+- -------
+- tt1 : double array
+- tt2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T d b t t
+- - - - - - - - - -
+-
+- Time scale transformation: Barycentric Dynamical Time, TDB, to
+- Terrestrial Time, TT.
+-
+- Given:
+- tdb1,tdb2 double TDB as a 2-part Julian Date
+- dtr double TDB-TT in seconds
+-
+- Returned:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tdb1+tdb2 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where tdb1 is the Julian
+- Day Number and tdb2 is the fraction of a day. The returned
+- tt1,tt2 follow suit.
+-
+- 2) The argument dtr represents the quasi-periodic component of the
+- GR transformation between TT and TCB. It is dependent upon the
+- adopted solar-system ephemeris, and can be obtained by numerical
+- integration, by interrogating a precomputed time ephemeris or by
+- evaluating a model such as that implemented in the ERFA function
+- eraDtdb. The quantity is dominated by an annual term of 1.7 ms
+- amplitude.
+-
+- 3) TDB is essentially the same as Teph, the time argument for the
+- JPL solar system ephemerides.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- IAU 2006 Resolution 3
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tt1, tt2, c_retval = ufunc.tdbtt(tdb1, tdb2, dtr)
+- check_errwarn(c_retval, 'tdbtt')
+- return tt1, tt2
+-
+-
+-STATUS_CODES['tdbtt'] = {0: 'OK'}
+-
+-
+-def tttai(tt1, tt2):
+- """
+- Wrapper for ERFA function ``eraTttai``.
+-
+- Parameters
+- ----------
+- tt1 : double array
+- tt2 : double array
+-
+- Returns
+- -------
+- tai1 : double array
+- tai2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T t t a i
+- - - - - - - - - -
+-
+- Time scale transformation: Terrestrial Time, TT, to International
+- Atomic Time, TAI.
+-
+- Given:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned:
+- tai1,tai2 double TAI as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Note:
+-
+- tt1+tt2 is Julian Date, apportioned in any convenient way between
+- the two arguments, for example where tt1 is the Julian Day Number
+- and tt2 is the fraction of a day. The returned tai1,tai2 follow
+- suit.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tai1, tai2, c_retval = ufunc.tttai(tt1, tt2)
+- check_errwarn(c_retval, 'tttai')
+- return tai1, tai2
+-
+-
+-STATUS_CODES['tttai'] = {0: 'OK'}
+-
+-
+-def tttcg(tt1, tt2):
+- """
+- Wrapper for ERFA function ``eraTttcg``.
+-
+- Parameters
+- ----------
+- tt1 : double array
+- tt2 : double array
+-
+- Returns
+- -------
+- tcg1 : double array
+- tcg2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T t t c g
+- - - - - - - - - -
+-
+- Time scale transformation: Terrestrial Time, TT, to Geocentric
+- Coordinate Time, TCG.
+-
+- Given:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned:
+- tcg1,tcg2 double TCG as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Note:
+-
+- tt1+tt2 is Julian Date, apportioned in any convenient way between
+- the two arguments, for example where tt1 is the Julian Day Number
+- and tt2 is the fraction of a day. The returned tcg1,tcg2 follow
+- suit.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- IAU 2000 Resolution B1.9
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tcg1, tcg2, c_retval = ufunc.tttcg(tt1, tt2)
+- check_errwarn(c_retval, 'tttcg')
+- return tcg1, tcg2
+-
+-
+-STATUS_CODES['tttcg'] = {0: 'OK'}
+-
+-
+-def tttdb(tt1, tt2, dtr):
+- """
+- Wrapper for ERFA function ``eraTttdb``.
+-
+- Parameters
+- ----------
+- tt1 : double array
+- tt2 : double array
+- dtr : double array
+-
+- Returns
+- -------
+- tdb1 : double array
+- tdb2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T t t d b
+- - - - - - - - - -
+-
+- Time scale transformation: Terrestrial Time, TT, to Barycentric
+- Dynamical Time, TDB.
+-
+- Given:
+- tt1,tt2 double TT as a 2-part Julian Date
+- dtr double TDB-TT in seconds
+-
+- Returned:
+- tdb1,tdb2 double TDB as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tt1+tt2 is Julian Date, apportioned in any convenient way between
+- the two arguments, for example where tt1 is the Julian Day Number
+- and tt2 is the fraction of a day. The returned tdb1,tdb2 follow
+- suit.
+-
+- 2) The argument dtr represents the quasi-periodic component of the
+- GR transformation between TT and TCB. It is dependent upon the
+- adopted solar-system ephemeris, and can be obtained by numerical
+- integration, by interrogating a precomputed time ephemeris or by
+- evaluating a model such as that implemented in the ERFA function
+- eraDtdb. The quantity is dominated by an annual term of 1.7 ms
+- amplitude.
+-
+- 3) TDB is essentially the same as Teph, the time argument for the JPL
+- solar system ephemerides.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- IAU 2006 Resolution 3
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tdb1, tdb2, c_retval = ufunc.tttdb(tt1, tt2, dtr)
+- check_errwarn(c_retval, 'tttdb')
+- return tdb1, tdb2
+-
+-
+-STATUS_CODES['tttdb'] = {0: 'OK'}
+-
+-
+-def ttut1(tt1, tt2, dt):
+- """
+- Wrapper for ERFA function ``eraTtut1``.
+-
+- Parameters
+- ----------
+- tt1 : double array
+- tt2 : double array
+- dt : double array
+-
+- Returns
+- -------
+- ut11 : double array
+- ut12 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T t u t 1
+- - - - - - - - - -
+-
+- Time scale transformation: Terrestrial Time, TT, to Universal Time,
+- UT1.
+-
+- Given:
+- tt1,tt2 double TT as a 2-part Julian Date
+- dt double TT-UT1 in seconds
+-
+- Returned:
+- ut11,ut12 double UT1 as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) tt1+tt2 is Julian Date, apportioned in any convenient way between
+- the two arguments, for example where tt1 is the Julian Day Number
+- and tt2 is the fraction of a day. The returned ut11,ut12 follow
+- suit.
+-
+- 2) The argument dt is classical Delta T.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ut11, ut12, c_retval = ufunc.ttut1(tt1, tt2, dt)
+- check_errwarn(c_retval, 'ttut1')
+- return ut11, ut12
+-
+-
+-STATUS_CODES['ttut1'] = {0: 'OK'}
+-
+-
+-def ut1tai(ut11, ut12, dta):
+- """
+- Wrapper for ERFA function ``eraUt1tai``.
+-
+- Parameters
+- ----------
+- ut11 : double array
+- ut12 : double array
+- dta : double array
+-
+- Returns
+- -------
+- tai1 : double array
+- tai2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a U t 1 t a i
+- - - - - - - - - - -
+-
+- Time scale transformation: Universal Time, UT1, to International
+- Atomic Time, TAI.
+-
+- Given:
+- ut11,ut12 double UT1 as a 2-part Julian Date
+- dta double UT1-TAI in seconds
+-
+- Returned:
+- tai1,tai2 double TAI as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) ut11+ut12 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where ut11 is the Julian
+- Day Number and ut12 is the fraction of a day. The returned
+- tai1,tai2 follow suit.
+-
+- 2) The argument dta, i.e. UT1-TAI, is an observed quantity, and is
+- available from IERS tabulations.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tai1, tai2, c_retval = ufunc.ut1tai(ut11, ut12, dta)
+- check_errwarn(c_retval, 'ut1tai')
+- return tai1, tai2
+-
+-
+-STATUS_CODES['ut1tai'] = {0: 'OK'}
+-
+-
+-def ut1tt(ut11, ut12, dt):
+- """
+- Wrapper for ERFA function ``eraUt1tt``.
+-
+- Parameters
+- ----------
+- ut11 : double array
+- ut12 : double array
+- dt : double array
+-
+- Returns
+- -------
+- tt1 : double array
+- tt2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a U t 1 t t
+- - - - - - - - - -
+-
+- Time scale transformation: Universal Time, UT1, to Terrestrial
+- Time, TT.
+-
+- Given:
+- ut11,ut12 double UT1 as a 2-part Julian Date
+- dt double TT-UT1 in seconds
+-
+- Returned:
+- tt1,tt2 double TT as a 2-part Julian Date
+-
+- Returned (function value):
+- int status: 0 = OK
+-
+- Notes:
+-
+- 1) ut11+ut12 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where ut11 is the Julian
+- Day Number and ut12 is the fraction of a day. The returned
+- tt1,tt2 follow suit.
+-
+- 2) The argument dt is classical Delta T.
+-
+- Reference:
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tt1, tt2, c_retval = ufunc.ut1tt(ut11, ut12, dt)
+- check_errwarn(c_retval, 'ut1tt')
+- return tt1, tt2
+-
+-
+-STATUS_CODES['ut1tt'] = {0: 'OK'}
+-
+-
+-def ut1utc(ut11, ut12, dut1):
+- """
+- Wrapper for ERFA function ``eraUt1utc``.
+-
+- Parameters
+- ----------
+- ut11 : double array
+- ut12 : double array
+- dut1 : double array
+-
+- Returns
+- -------
+- utc1 : double array
+- utc2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a U t 1 u t c
+- - - - - - - - - - -
+-
+- Time scale transformation: Universal Time, UT1, to Coordinated
+- Universal Time, UTC.
+-
+- Given:
+- ut11,ut12 double UT1 as a 2-part Julian Date (Note 1)
+- dut1 double Delta UT1: UT1-UTC in seconds (Note 2)
+-
+- Returned:
+- utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 3,4)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 5)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) ut11+ut12 is Julian Date, apportioned in any convenient way
+- between the two arguments, for example where ut11 is the Julian
+- Day Number and ut12 is the fraction of a day. The returned utc1
+- and utc2 form an analogous pair, except that a special convention
+- is used, to deal with the problem of leap seconds - see Note 3.
+-
+- 2) Delta UT1 can be obtained from tabulations provided by the
+- International Earth Rotation and Reference Systems Service. The
+- value changes abruptly by 1s at a leap second; however, close to
+- a leap second the algorithm used here is tolerant of the "wrong"
+- choice of value being made.
+-
+- 3) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The convention in the present
+- function is that the returned quasi JD day UTC1+UTC2 represents
+- UTC days whether the length is 86399, 86400 or 86401 SI seconds.
+-
+- 4) The function eraD2dtf can be used to transform the UTC quasi-JD
+- into calendar date and clock time, including UTC leap second
+- handling.
+-
+- 5) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- Called:
+- eraJd2cal JD to Gregorian calendar
+- eraDat delta(AT) = TAI-UTC
+- eraCal2jd Gregorian calendar to JD
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- utc1, utc2, c_retval = ufunc.ut1utc(ut11, ut12, dut1)
+- check_errwarn(c_retval, 'ut1utc')
+- return utc1, utc2
+-
+-
+-STATUS_CODES['ut1utc'] = {1: 'dubious year (Note 5)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def utctai(utc1, utc2):
+- """
+- Wrapper for ERFA function ``eraUtctai``.
+-
+- Parameters
+- ----------
+- utc1 : double array
+- utc2 : double array
+-
+- Returns
+- -------
+- tai1 : double array
+- tai2 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a U t c t a i
+- - - - - - - - - - -
+-
+- Time scale transformation: Coordinated Universal Time, UTC, to
+- International Atomic Time, TAI.
+-
+- Given:
+- utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4)
+-
+- Returned:
+- tai1,tai2 double TAI as a 2-part Julian Date (Note 5)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 3)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- 2) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The convention in the present
+- function is that the JD day represents UTC days whether the
+- length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era
+- there were smaller jumps (in either direction) each time the
+- linear UTC(TAI) expression was changed, and these "mini-leaps"
+- are also included in the ERFA convention.
+-
+- 3) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- 4) The function eraDtf2d converts from calendar date and time of day
+- into 2-part Julian Date, and in the case of UTC implements the
+- leap-second-ambiguity convention described above.
+-
+- 5) The returned TAI1,TAI2 are such that their sum is the TAI Julian
+- Date.
+-
+- Called:
+- eraJd2cal JD to Gregorian calendar
+- eraDat delta(AT) = TAI-UTC
+- eraCal2jd Gregorian calendar to JD
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- tai1, tai2, c_retval = ufunc.utctai(utc1, utc2)
+- check_errwarn(c_retval, 'utctai')
+- return tai1, tai2
+-
+-
+-STATUS_CODES['utctai'] = {1: 'dubious year (Note 3)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def utcut1(utc1, utc2, dut1):
+- """
+- Wrapper for ERFA function ``eraUtcut1``.
+-
+- Parameters
+- ----------
+- utc1 : double array
+- utc2 : double array
+- dut1 : double array
+-
+- Returns
+- -------
+- ut11 : double array
+- ut12 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a U t c u t 1
+- - - - - - - - - - -
+-
+- Time scale transformation: Coordinated Universal Time, UTC, to
+- Universal Time, UT1.
+-
+- Given:
+- utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4)
+- dut1 double Delta UT1 = UT1-UTC in seconds (Note 5)
+-
+- Returned:
+- ut11,ut12 double UT1 as a 2-part Julian Date (Note 6)
+-
+- Returned (function value):
+- int status: +1 = dubious year (Note 3)
+- 0 = OK
+- -1 = unacceptable date
+-
+- Notes:
+-
+- 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any
+- convenient way between the two arguments, for example where utc1
+- is the Julian Day Number and utc2 is the fraction of a day.
+-
+- 2) JD cannot unambiguously represent UTC during a leap second unless
+- special measures are taken. The convention in the present
+- function is that the JD day represents UTC days whether the
+- length is 86399, 86400 or 86401 SI seconds.
+-
+- 3) The warning status "dubious year" flags UTCs that predate the
+- introduction of the time scale or that are too far in the future
+- to be trusted. See eraDat for further details.
+-
+- 4) The function eraDtf2d converts from calendar date and time of
+- day into 2-part Julian Date, and in the case of UTC implements
+- the leap-second-ambiguity convention described above.
+-
+- 5) Delta UT1 can be obtained from tabulations provided by the
+- International Earth Rotation and Reference Systems Service.
+- It is the caller's responsibility to supply a dut1 argument
+- containing the UT1-UTC value that matches the given UTC.
+-
+- 6) The returned ut11,ut12 are such that their sum is the UT1 Julian
+- Date.
+-
+- References:
+-
+- McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003),
+- IERS Technical Note No. 32, BKG (2004)
+-
+- Explanatory Supplement to the Astronomical Almanac,
+- P. Kenneth Seidelmann (ed), University Science Books (1992)
+-
+- Called:
+- eraJd2cal JD to Gregorian calendar
+- eraDat delta(AT) = TAI-UTC
+- eraUtctai UTC to TAI
+- eraTaiut1 TAI to UT1
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- ut11, ut12, c_retval = ufunc.utcut1(utc1, utc2, dut1)
+- check_errwarn(c_retval, 'utcut1')
+- return ut11, ut12
+-
+-
+-STATUS_CODES['utcut1'] = {1: 'dubious year (Note 3)', 0: 'OK', -1: 'unacceptable date'}
+-
+-
+-def ae2hd(az, el, phi):
+- """
+- Wrapper for ERFA function ``eraAe2hd``.
+-
+- Parameters
+- ----------
+- az : double array
+- el : double array
+- phi : double array
+-
+- Returns
+- -------
+- ha : double array
+- dec : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a A e 2 h d
+- - - - - - - - - -
+-
+- Horizon to equatorial coordinates: transform azimuth and altitude
+- to hour angle and declination.
+-
+- Given:
+- az double azimuth
+- el double altitude (informally, elevation)
+- phi double site latitude
+-
+- Returned:
+- ha double hour angle (local)
+- dec double declination
+-
+- Notes:
+-
+- 1) All the arguments are angles in radians.
+-
+- 2) The sign convention for azimuth is north zero, east +pi/2.
+-
+- 3) HA is returned in the range +/-pi. Declination is returned in
+- the range +/-pi/2.
+-
+- 4) The latitude phi is pi/2 minus the angle between the Earth's
+- rotation axis and the adopted zenith. In many applications it
+- will be sufficient to use the published geodetic latitude of the
+- site. In very precise (sub-arcsecond) applications, phi can be
+- corrected for polar motion.
+-
+- 5) The azimuth az must be with respect to the rotational north pole,
+- as opposed to the ITRS pole, and an azimuth with respect to north
+- on a map of the Earth's surface will need to be adjusted for
+- polar motion if sub-arcsecond accuracy is required.
+-
+- 6) Should the user wish to work with respect to the astronomical
+- zenith rather than the geodetic zenith, phi will need to be
+- adjusted for deflection of the vertical (often tens of
+- arcseconds), and the zero point of ha will also be affected.
+-
+- 7) The transformation is the same as Ve = Ry(phi-pi/2)*Rz(pi)*Vh,
+- where Ve and Vh are lefthanded unit vectors in the (ha,dec) and
+- (az,el) systems respectively and Rz and Ry are rotations about
+- first the z-axis and then the y-axis. (n.b. Rz(pi) simply
+- reverses the signs of the x and y components.) For efficiency,
+- the algorithm is written out rather than calling other utility
+- functions. For applications that require even greater
+- efficiency, additional savings are possible if constant terms
+- such as functions of latitude are computed once and for all.
+-
+- 8) Again for efficiency, no range checking of arguments is carried
+- out.
+-
+- Last revision: 2017 September 12
+-
+- ERFA release 2019-07-22
+-
+- Copyright (C) 2019 IAU ERFA Board. See notes at end.
+-
+- """
+- ha, dec = ufunc.ae2hd(az, el, phi)
+- return ha, dec
+-
+-
+-def hd2ae(ha, dec, phi):
+- """
+- Wrapper for ERFA function ``eraHd2ae``.
+-
+- Parameters
+- ----------
+- ha : double array
+- dec : double array
+- phi : double array
+-
+- Returns
+- -------
+- az : double array
+- el : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a H d 2 a e
+- - - - - - - - - -
+-
+- Equatorial to horizon coordinates: transform hour angle and
+- declination to azimuth and altitude.
+-
+- Given:
+- ha double hour angle (local)
+- dec double declination
+- phi double site latitude
+-
+- Returned:
+- *az double azimuth
+- *el double altitude (informally, elevation)
+-
+- Notes:
+-
+- 1) All the arguments are angles in radians.
+-
+- 2) Azimuth is returned in the range 0-2pi; north is zero, and east
+- is +pi/2. Altitude is returned in the range +/- pi/2.
+-
+- 3) The latitude phi is pi/2 minus the angle between the Earth's
+- rotation axis and the adopted zenith. In many applications it
+- will be sufficient to use the published geodetic latitude of the
+- site. In very precise (sub-arcsecond) applications, phi can be
+- corrected for polar motion.
+-
+- 4) The returned azimuth az is with respect to the rotational north
+- pole, as opposed to the ITRS pole, and for sub-arcsecond
+- accuracy will need to be adjusted for polar motion if it is to
+- be with respect to north on a map of the Earth's surface.
+-
+- 5) Should the user wish to work with respect to the astronomical
+- zenith rather than the geodetic zenith, phi will need to be
+- adjusted for deflection of the vertical (often tens of
+- arcseconds), and the zero point of the hour angle ha will also
+- be affected.
+-
+- 6) The transformation is the same as Vh = Rz(pi)*Ry(pi/2-phi)*Ve,
+- where Vh and Ve are lefthanded unit vectors in the (az,el) and
+- (ha,dec) systems respectively and Ry and Rz are rotations about
+- first the y-axis and then the z-axis. (n.b. Rz(pi) simply
+- reverses the signs of the x and y components.) For efficiency,
+- the algorithm is written out rather than calling other utility
+- functions. For applications that require even greater
+- efficiency, additional savings are possible if constant terms
+- such as functions of latitude are computed once and for all.
+-
+- 7) Again for efficiency, no range checking of arguments is carried
+- out.
+-
+- Last revision: 2017 September 12
+-
+- ERFA release 2019-07-22
+-
+- Copyright (C) 2019 IAU ERFA Board. See notes at end.
+-
+- """
+- az, el = ufunc.hd2ae(ha, dec, phi)
+- return az, el
+-
+-
+-def hd2pa(ha, dec, phi):
+- """
+- Wrapper for ERFA function ``eraHd2pa``.
+-
+- Parameters
+- ----------
+- ha : double array
+- dec : double array
+- phi : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a H d 2 p a
+- - - - - - - - - -
+-
+- Parallactic angle for a given hour angle and declination.
+-
+- Given:
+- ha double hour angle
+- dec double declination
+- phi double site latitude
+-
+- Returned (function value):
+- double parallactic angle
+-
+- Notes:
+-
+- 1) All the arguments are angles in radians.
+-
+- 2) The parallactic angle at a point in the sky is the position
+- angle of the vertical, i.e. the angle between the directions to
+- the north celestial pole and to the zenith respectively.
+-
+- 3) The result is returned in the range -pi to +pi.
+-
+- 4) At the pole itself a zero result is returned.
+-
+- 5) The latitude phi is pi/2 minus the angle between the Earth's
+- rotation axis and the adopted zenith. In many applications it
+- will be sufficient to use the published geodetic latitude of the
+- site. In very precise (sub-arcsecond) applications, phi can be
+- corrected for polar motion.
+-
+- 6) Should the user wish to work with respect to the astronomical
+- zenith rather than the geodetic zenith, phi will need to be
+- adjusted for deflection of the vertical (often tens of
+- arcseconds), and the zero point of the hour angle ha will also
+- be affected.
+-
+- Reference:
+- Smart, W.M., "Spherical Astronomy", Cambridge University Press,
+- 6th edition (Green, 1977), p49.
+-
+- Last revision: 2017 September 12
+-
+- ERFA release 2019-07-22
+-
+- Copyright (C) 2019 IAU ERFA Board. See notes at end.
+-
+- """
+- c_retval = ufunc.hd2pa(ha, dec, phi)
+- return c_retval
+-
+-
+-def tpors(xi, eta, a, b):
+- """
+- Wrapper for ERFA function ``eraTpors``.
+-
+- Parameters
+- ----------
+- xi : double array
+- eta : double array
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- a01 : double array
+- b01 : double array
+- a02 : double array
+- b02 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p o r s
+- - - - - - - - - -
+-
+- In the tangent plane projection, given the rectangular coordinates
+- of a star and its spherical coordinates, determine the spherical
+- coordinates of the tangent point.
+-
+- Given:
+- xi,eta double rectangular coordinates of star image (Note 2)
+- a,b double star's spherical coordinates (Note 3)
+-
+- Returned:
+- *a01,*b01 double tangent point's spherical coordinates, Soln. 1
+- *a02,*b02 double tangent point's spherical coordinates, Soln. 2
+-
+- Returned (function value):
+- int number of solutions:
+- 0 = no solutions returned (Note 5)
+- 1 = only the first solution is useful (Note 6)
+- 2 = both solutions are useful (Note 6)
+-
+- Notes:
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the spherical coordinates are observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". If the spherical coordinates are with
+- respect to a right-handed triad, (xi,eta) are also right-handed.
+- The units of (xi,eta) are, effectively, radians at the tangent
+- point.
+-
+- 3) All angular arguments are in radians.
+-
+- 4) The angles a01 and a02 are returned in the range 0-2pi. The
+- angles b01 and b02 are returned in the range +/-pi, but in the
+- usual, non-pole-crossing, case, the range is +/-pi/2.
+-
+- 5) Cases where there is no solution can arise only near the poles.
+- For example, it is clearly impossible for a star at the pole
+- itself to have a non-zero xi value, and hence it is meaningless
+- to ask where the tangent point would have to be to bring about
+- this combination of xi and dec.
+-
+- 6) Also near the poles, cases can arise where there are two useful
+- solutions. The return value indicates whether the second of the
+- two solutions returned is useful; 1 indicates only one useful
+- solution, the usual case.
+-
+- 7) The basis of the algorithm is to solve the spherical triangle PSC,
+- where P is the north celestial pole, S is the star and C is the
+- tangent point. The spherical coordinates of the tangent point are
+- [a0,b0]; writing rho^2 = (xi^2+eta^2) and r^2 = (1+rho^2), side c
+- is then (pi/2-b), side p is sqrt(xi^2+eta^2) and side s (to be
+- found) is (pi/2-b0). Angle C is given by sin(C) = xi/rho and
+- cos(C) = eta/rho. Angle P (to be found) is the longitude
+- difference between star and tangent point (a-a0).
+-
+- 8) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- eraTpxes eraTpxev xi,eta
+- eraTpsts eraTpstv star
+- > eraTpors < eraTporv origin
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- a01, b01, a02, b02, c_retval = ufunc.tpors(xi, eta, a, b)
+- check_errwarn(c_retval, 'tpors')
+- return a01, b01, a02, b02
+-
+-
+-
+-
+-def tporv(xi, eta, v):
+- """
+- Wrapper for ERFA function ``eraTporv``.
+-
+- Parameters
+- ----------
+- xi : double array
+- eta : double array
+- v : double array
+-
+- Returns
+- -------
+- v01 : double array
+- v02 : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p o r v
+- - - - - - - - - -
+-
+- In the tangent plane projection, given the rectangular coordinates
+- of a star and its direction cosines, determine the direction
+- cosines of the tangent point.
+-
+- Given:
+- xi,eta double rectangular coordinates of star image (Note 2)
+- v double[3] star's direction cosines (Note 3)
+-
+- Returned:
+- v01 double[3] tangent point's direction cosines, Solution 1
+- v02 double[3] tangent point's direction cosines, Solution 2
+-
+- Returned (function value):
+- int number of solutions:
+- 0 = no solutions returned (Note 4)
+- 1 = only the first solution is useful (Note 5)
+- 2 = both solutions are useful (Note 5)
+-
+- Notes:
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the direction cosines represent observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". If the direction cosines are with
+- respect to a right-handed triad, (xi,eta) are also right-handed.
+- The units of (xi,eta) are, effectively, radians at the tangent
+- point.
+-
+- 3) The vector v must be of unit length or the result will be wrong.
+-
+- 4) Cases where there is no solution can arise only near the poles.
+- For example, it is clearly impossible for a star at the pole
+- itself to have a non-zero xi value, and hence it is meaningless
+- to ask where the tangent point would have to be.
+-
+- 5) Also near the poles, cases can arise where there are two useful
+- solutions. The return value indicates whether the second of the
+- two solutions returned is useful; 1 indicates only one useful
+- solution, the usual case.
+-
+- 6) The basis of the algorithm is to solve the spherical triangle
+- PSC, where P is the north celestial pole, S is the star and C is
+- the tangent point. Calling the celestial spherical coordinates
+- of the star and tangent point (a,b) and (a0,b0) respectively, and
+- writing rho^2 = (xi^2+eta^2) and r^2 = (1+rho^2), and
+- transforming the vector v into (a,b) in the normal way, side c is
+- then (pi/2-b), side p is sqrt(xi^2+eta^2) and side s (to be
+- found) is (pi/2-b0), while angle C is given by sin(C) = xi/rho
+- and cos(C) = eta/rho; angle P (to be found) is (a-a0). After
+- solving the spherical triangle, the result (a0,b0) can be
+- expressed in vector form as v0.
+-
+- 7) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- eraTpxes eraTpxev xi,eta
+- eraTpsts eraTpstv star
+- eraTpors > eraTporv < origin
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- v01, v02, c_retval = ufunc.tporv(xi, eta, v)
+- check_errwarn(c_retval, 'tporv')
+- return v01, v02
+-
+-
+-
+-
+-def tpsts(xi, eta, a0, b0):
+- """
+- Wrapper for ERFA function ``eraTpsts``.
+-
+- Parameters
+- ----------
+- xi : double array
+- eta : double array
+- a0 : double array
+- b0 : double array
+-
+- Returns
+- -------
+- a : double array
+- b : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p s t s
+- - - - - - - - - -
+-
+- In the tangent plane projection, given the star's rectangular
+- coordinates and the spherical coordinates of the tangent point,
+- solve for the spherical coordinates of the star.
+-
+- Given:
+- xi,eta double rectangular coordinates of star image (Note 2)
+- a0,b0 double tangent point's spherical coordinates
+-
+- Returned:
+- *a,*b double star's spherical coordinates
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the spherical coordinates are observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". If the spherical coordinates are with
+- respect to a right-handed triad, (xi,eta) are also right-handed.
+- The units of (xi,eta) are, effectively, radians at the tangent
+- point.
+-
+- 3) All angular arguments are in radians.
+-
+- 4) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- eraTpxes eraTpxev xi,eta
+- > eraTpsts < eraTpstv star
+- eraTpors eraTporv origin
+-
+- Called:
+- eraAnp normalize angle into range 0 to 2pi
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- a, b = ufunc.tpsts(xi, eta, a0, b0)
+- return a, b
+-
+-
+-def tpstv(xi, eta, v0):
+- """
+- Wrapper for ERFA function ``eraTpstv``.
+-
+- Parameters
+- ----------
+- xi : double array
+- eta : double array
+- v0 : double array
+-
+- Returns
+- -------
+- v : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p s t v
+- - - - - - - - - -
+-
+- In the tangent plane projection, given the star's rectangular
+- coordinates and the direction cosines of the tangent point, solve
+- for the direction cosines of the star.
+-
+- Given:
+- xi,eta double rectangular coordinates of star image (Note 2)
+- v0 double[3] tangent point's direction cosines
+-
+- Returned:
+- v double[3] star's direction cosines
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the direction cosines represent observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". If the direction cosines are with
+- respect to a right-handed triad, (xi,eta) are also right-handed.
+- The units of (xi,eta) are, effectively, radians at the tangent
+- point.
+-
+- 3) The method used is to complete the star vector in the (xi,eta)
+- based triad and normalize it, then rotate the triad to put the
+- tangent point at the pole with the x-axis aligned to zero
+- longitude. Writing (a0,b0) for the celestial spherical
+- coordinates of the tangent point, the sequence of rotations is
+- (b-pi/2) around the x-axis followed by (-a-pi/2) around the
+- z-axis.
+-
+- 4) If vector v0 is not of unit length, the returned vector v will
+- be wrong.
+-
+- 5) If vector v0 points at a pole, the returned vector v will be
+- based on the arbitrary assumption that the longitude coordinate
+- of the tangent point is zero.
+-
+- 6) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- eraTpxes eraTpxev xi,eta
+- eraTpsts > eraTpstv < star
+- eraTpors eraTporv origin
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- v = ufunc.tpstv(xi, eta, v0)
+- return v
+-
+-
+-def tpxes(a, b, a0, b0):
+- """
+- Wrapper for ERFA function ``eraTpxes``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+- a0 : double array
+- b0 : double array
+-
+- Returns
+- -------
+- xi : double array
+- eta : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p x e s
+- - - - - - - - - -
+-
+- In the tangent plane projection, given celestial spherical
+- coordinates for a star and the tangent point, solve for the star's
+- rectangular coordinates in the tangent plane.
+-
+- Given:
+- a,b double star's spherical coordinates
+- a0,b0 double tangent point's spherical coordinates
+-
+- Returned:
+- *xi,*eta double rectangular coordinates of star image (Note 2)
+-
+- Returned (function value):
+- int status: 0 = OK
+- 1 = star too far from axis
+- 2 = antistar on tangent plane
+- 3 = antistar too far from axis
+-
+- Notes:
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the spherical coordinates are observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". For right-handed spherical coordinates,
+- (xi,eta) are also right-handed. The units of (xi,eta) are,
+- effectively, radians at the tangent point.
+-
+- 3) All angular arguments are in radians.
+-
+- 4) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- > eraTpxes < eraTpxev xi,eta
+- eraTpsts eraTpstv star
+- eraTpors eraTporv origin
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- xi, eta, c_retval = ufunc.tpxes(a, b, a0, b0)
+- check_errwarn(c_retval, 'tpxes')
+- return xi, eta
+-
+-
+-STATUS_CODES['tpxes'] = {0: 'OK', 1: 'star too far from axis', 2: 'antistar on tangent plane', 3: 'antistar too far from axis'}
+-
+-
+-def tpxev(v, v0):
+- """
+- Wrapper for ERFA function ``eraTpxev``.
+-
+- Parameters
+- ----------
+- v : double array
+- v0 : double array
+-
+- Returns
+- -------
+- xi : double array
+- eta : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T p x e v
+- - - - - - - - - -
+-
+- In the tangent plane projection, given celestial direction cosines
+- for a star and the tangent point, solve for the star's rectangular
+- coordinates in the tangent plane.
+-
+- Given:
+- v double[3] direction cosines of star (Note 4)
+- v0 double[3] direction cosines of tangent point (Note 4)
+-
+- Returned:
+- *xi,*eta double tangent plane coordinates of star
+-
+- Returned (function value):
+- int status: 0 = OK
+- 1 = star too far from axis
+- 2 = antistar on tangent plane
+- 3 = antistar too far from axis
+-
+- Notes:
+-
+- 1) The tangent plane projection is also called the "gnomonic
+- projection" and the "central projection".
+-
+- 2) The eta axis points due north in the adopted coordinate system.
+- If the direction cosines represent observed (RA,Dec), the tangent
+- plane coordinates (xi,eta) are conventionally called the
+- "standard coordinates". If the direction cosines are with
+- respect to a right-handed triad, (xi,eta) are also right-handed.
+- The units of (xi,eta) are, effectively, radians at the tangent
+- point.
+-
+- 3) The method used is to extend the star vector to the tangent
+- plane and then rotate the triad so that (x,y) becomes (xi,eta).
+- Writing (a,b) for the celestial spherical coordinates of the
+- star, the sequence of rotations is (a+pi/2) around the z-axis
+- followed by (pi/2-b) around the x-axis.
+-
+- 4) If vector v0 is not of unit length, or if vector v is of zero
+- length, the results will be wrong.
+-
+- 5) If v0 points at a pole, the returned (xi,eta) will be based on
+- the arbitrary assumption that the longitude coordinate of the
+- tangent point is zero.
+-
+- 6) This function is a member of the following set:
+-
+- spherical vector solve for
+-
+- eraTpxes > eraTpxev < xi,eta
+- eraTpsts eraTpstv star
+- eraTpors eraTporv origin
+-
+- References:
+-
+- Calabretta M.R. & Greisen, E.W., 2002, "Representations of
+- celestial coordinates in FITS", Astron.Astrophys. 395, 1077
+-
+- Green, R.M., "Spherical Astronomy", Cambridge University Press,
+- 1987, Chapter 13.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- xi, eta, c_retval = ufunc.tpxev(v, v0)
+- check_errwarn(c_retval, 'tpxev')
+- return xi, eta
+-
+-
+-STATUS_CODES['tpxev'] = {0: 'OK', 1: 'star too far from axis', 2: 'antistar on tangent plane', 3: 'antistar too far from axis'}
+-
+-
+-def a2af(ndp, angle):
+- """
+- Wrapper for ERFA function ``eraA2af``.
+-
+- Parameters
+- ----------
+- ndp : int array
+- angle : double array
+-
+- Returns
+- -------
+- sign : char array
+- idmsf : int array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A 2 a f
+- - - - - - - - -
+-
+- Decompose radians into degrees, arcminutes, arcseconds, fraction.
+-
+- Given:
+- ndp int resolution (Note 1)
+- angle double angle in radians
+-
+- Returned:
+- sign char '+' or '-'
+- idmsf int[4] degrees, arcminutes, arcseconds, fraction
+-
+- Called:
+- eraD2tf decompose days to hms
+-
+- Notes:
+-
+- 1) The argument ndp is interpreted as follows:
+-
+- ndp resolution
+- : ...0000 00 00
+- -7 1000 00 00
+- -6 100 00 00
+- -5 10 00 00
+- -4 1 00 00
+- -3 0 10 00
+- -2 0 01 00
+- -1 0 00 10
+- 0 0 00 01
+- 1 0 00 00.1
+- 2 0 00 00.01
+- 3 0 00 00.001
+- : 0 00 00.000...
+-
+- 2) The largest positive useful value for ndp is determined by the
+- size of angle, the format of doubles on the target platform, and
+- the risk of overflowing idmsf[3]. On a typical platform, for
+- angle up to 2pi, the available floating-point precision might
+- correspond to ndp=12. However, the practical limit is typically
+- ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is
+- only 16 bits.
+-
+- 3) The absolute value of angle may exceed 2pi. In cases where it
+- does not, it is up to the caller to test for and handle the
+- case where angle is very nearly 2pi and rounds up to 360 degrees,
+- by testing for idmsf[0]=360 and setting idmsf[0-3] to zero.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- sign, idmsf = ufunc.a2af(ndp, angle)
+- sign = sign.view(dt_bytes1)
+- return sign, idmsf
+-
+-
+-def a2tf(ndp, angle):
+- """
+- Wrapper for ERFA function ``eraA2tf``.
+-
+- Parameters
+- ----------
+- ndp : int array
+- angle : double array
+-
+- Returns
+- -------
+- sign : char array
+- ihmsf : int array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A 2 t f
+- - - - - - - - -
+-
+- Decompose radians into hours, minutes, seconds, fraction.
+-
+- Given:
+- ndp int resolution (Note 1)
+- angle double angle in radians
+-
+- Returned:
+- sign char '+' or '-'
+- ihmsf int[4] hours, minutes, seconds, fraction
+-
+- Called:
+- eraD2tf decompose days to hms
+-
+- Notes:
+-
+- 1) The argument ndp is interpreted as follows:
+-
+- ndp resolution
+- : ...0000 00 00
+- -7 1000 00 00
+- -6 100 00 00
+- -5 10 00 00
+- -4 1 00 00
+- -3 0 10 00
+- -2 0 01 00
+- -1 0 00 10
+- 0 0 00 01
+- 1 0 00 00.1
+- 2 0 00 00.01
+- 3 0 00 00.001
+- : 0 00 00.000...
+-
+- 2) The largest positive useful value for ndp is determined by the
+- size of angle, the format of doubles on the target platform, and
+- the risk of overflowing ihmsf[3]. On a typical platform, for
+- angle up to 2pi, the available floating-point precision might
+- correspond to ndp=12. However, the practical limit is typically
+- ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is
+- only 16 bits.
+-
+- 3) The absolute value of angle may exceed 2pi. In cases where it
+- does not, it is up to the caller to test for and handle the
+- case where angle is very nearly 2pi and rounds up to 24 hours,
+- by testing for ihmsf[0]=24 and setting ihmsf[0-3] to zero.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- sign, ihmsf = ufunc.a2tf(ndp, angle)
+- sign = sign.view(dt_bytes1)
+- return sign, ihmsf
+-
+-
+-def af2a(s, ideg, iamin, asec):
+- """
+- Wrapper for ERFA function ``eraAf2a``.
+-
+- Parameters
+- ----------
+- s : char array
+- ideg : int array
+- iamin : int array
+- asec : double array
+-
+- Returns
+- -------
+- rad : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A f 2 a
+- - - - - - - - -
+-
+- Convert degrees, arcminutes, arcseconds to radians.
+-
+- Given:
+- s char sign: '-' = negative, otherwise positive
+- ideg int degrees
+- iamin int arcminutes
+- asec double arcseconds
+-
+- Returned:
+- rad double angle in radians
+-
+- Returned (function value):
+- int status: 0 = OK
+- 1 = ideg outside range 0-359
+- 2 = iamin outside range 0-59
+- 3 = asec outside range 0-59.999...
+-
+- Notes:
+-
+- 1) The result is computed even if any of the range checks fail.
+-
+- 2) Negative ideg, iamin and/or asec produce a warning status, but
+- the absolute value is used in the conversion.
+-
+- 3) If there are multiple errors, the status value reflects only the
+- first, the smallest taking precedence.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rad, c_retval = ufunc.af2a(s, ideg, iamin, asec)
+- check_errwarn(c_retval, 'af2a')
+- return rad
+-
+-
+-STATUS_CODES['af2a'] = {0: 'OK', 1: 'ideg outside range 0-359', 2: 'iamin outside range 0-59', 3: 'asec outside range 0-59.999...'}
+-
+-
+-def anp(a):
+- """
+- Wrapper for ERFA function ``eraAnp``.
+-
+- Parameters
+- ----------
+- a : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a A n p
+- - - - - - - -
+-
+- Normalize angle into the range 0 <= a < 2pi.
+-
+- Given:
+- a double angle (radians)
+-
+- Returned (function value):
+- double angle in range 0-2pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.anp(a)
+- return c_retval
+-
+-
+-def anpm(a):
+- """
+- Wrapper for ERFA function ``eraAnpm``.
+-
+- Parameters
+- ----------
+- a : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a A n p m
+- - - - - - - - -
+-
+- Normalize angle into the range -pi <= a < +pi.
+-
+- Given:
+- a double angle (radians)
+-
+- Returned (function value):
+- double angle in range +/-pi
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.anpm(a)
+- return c_retval
+-
+-
+-def d2tf(ndp, days):
+- """
+- Wrapper for ERFA function ``eraD2tf``.
+-
+- Parameters
+- ----------
+- ndp : int array
+- days : double array
+-
+- Returns
+- -------
+- sign : char array
+- ihmsf : int array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a D 2 t f
+- - - - - - - - -
+-
+- Decompose days to hours, minutes, seconds, fraction.
+-
+- Given:
+- ndp int resolution (Note 1)
+- days double interval in days
+-
+- Returned:
+- sign char '+' or '-'
+- ihmsf int[4] hours, minutes, seconds, fraction
+-
+- Notes:
+-
+- 1) The argument ndp is interpreted as follows:
+-
+- ndp resolution
+- : ...0000 00 00
+- -7 1000 00 00
+- -6 100 00 00
+- -5 10 00 00
+- -4 1 00 00
+- -3 0 10 00
+- -2 0 01 00
+- -1 0 00 10
+- 0 0 00 01
+- 1 0 00 00.1
+- 2 0 00 00.01
+- 3 0 00 00.001
+- : 0 00 00.000...
+-
+- 2) The largest positive useful value for ndp is determined by the
+- size of days, the format of double on the target platform, and
+- the risk of overflowing ihmsf[3]. On a typical platform, for
+- days up to 1.0, the available floating-point precision might
+- correspond to ndp=12. However, the practical limit is typically
+- ndp=9, set by the capacity of a 32-bit int, or ndp=4 if int is
+- only 16 bits.
+-
+- 3) The absolute value of days may exceed 1.0. In cases where it
+- does not, it is up to the caller to test for and handle the
+- case where days is very nearly 1.0 and rounds up to 24 hours,
+- by testing for ihmsf[0]=24 and setting ihmsf[0-3] to zero.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- sign, ihmsf = ufunc.d2tf(ndp, days)
+- sign = sign.view(dt_bytes1)
+- return sign, ihmsf
+-
+-
+-def tf2a(s, ihour, imin, sec):
+- """
+- Wrapper for ERFA function ``eraTf2a``.
+-
+- Parameters
+- ----------
+- s : char array
+- ihour : int array
+- imin : int array
+- sec : double array
+-
+- Returns
+- -------
+- rad : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a T f 2 a
+- - - - - - - - -
+-
+- Convert hours, minutes, seconds to radians.
+-
+- Given:
+- s char sign: '-' = negative, otherwise positive
+- ihour int hours
+- imin int minutes
+- sec double seconds
+-
+- Returned:
+- rad double angle in radians
+-
+- Returned (function value):
+- int status: 0 = OK
+- 1 = ihour outside range 0-23
+- 2 = imin outside range 0-59
+- 3 = sec outside range 0-59.999...
+-
+- Notes:
+-
+- 1) The result is computed even if any of the range checks fail.
+-
+- 2) Negative ihour, imin and/or sec produce a warning status, but
+- the absolute value is used in the conversion.
+-
+- 3) If there are multiple errors, the status value reflects only the
+- first, the smallest taking precedence.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rad, c_retval = ufunc.tf2a(s, ihour, imin, sec)
+- check_errwarn(c_retval, 'tf2a')
+- return rad
+-
+-
+-STATUS_CODES['tf2a'] = {0: 'OK', 1: 'ihour outside range 0-23', 2: 'imin outside range 0-59', 3: 'sec outside range 0-59.999...'}
+-
+-
+-def tf2d(s, ihour, imin, sec):
+- """
+- Wrapper for ERFA function ``eraTf2d``.
+-
+- Parameters
+- ----------
+- s : char array
+- ihour : int array
+- imin : int array
+- sec : double array
+-
+- Returns
+- -------
+- days : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a T f 2 d
+- - - - - - - - -
+-
+- Convert hours, minutes, seconds to days.
+-
+- Given:
+- s char sign: '-' = negative, otherwise positive
+- ihour int hours
+- imin int minutes
+- sec double seconds
+-
+- Returned:
+- days double interval in days
+-
+- Returned (function value):
+- int status: 0 = OK
+- 1 = ihour outside range 0-23
+- 2 = imin outside range 0-59
+- 3 = sec outside range 0-59.999...
+-
+- Notes:
+-
+- 1) The result is computed even if any of the range checks fail.
+-
+- 2) Negative ihour, imin and/or sec produce a warning status, but
+- the absolute value is used in the conversion.
+-
+- 3) If there are multiple errors, the status value reflects only the
+- first, the smallest taking precedence.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- days, c_retval = ufunc.tf2d(s, ihour, imin, sec)
+- check_errwarn(c_retval, 'tf2d')
+- return days
+-
+-
+-STATUS_CODES['tf2d'] = {0: 'OK', 1: 'ihour outside range 0-23', 2: 'imin outside range 0-59', 3: 'sec outside range 0-59.999...'}
+-
+-
+-def rx(phi, r):
+- """
+- Wrapper for ERFA function ``eraRx``.
+-
+- Parameters
+- ----------
+- phi : double array
+- r : double array
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below. Note that, unlike the erfa routine,
+- the python wrapper does not change r in-place.
+-
+- - - - - - -
+- e r a R x
+- - - - - - -
+-
+- Rotate an r-matrix about the x-axis.
+-
+- Given:
+- phi double angle (radians)
+-
+- Given and returned:
+- r double[3][3] r-matrix, rotated
+-
+- Notes:
+-
+- 1) Calling this function with positive phi incorporates in the
+- supplied r-matrix r an additional rotation, about the x-axis,
+- anticlockwise as seen looking towards the origin from positive x.
+-
+- 2) The additional rotation can be represented by this matrix:
+-
+- ( 1 0 0 )
+- ( )
+- ( 0 + cos(phi) + sin(phi) )
+- ( )
+- ( 0 - sin(phi) + cos(phi) )
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.rx(phi, r)
+- return r
+-
+-
+-def ry(theta, r):
+- """
+- Wrapper for ERFA function ``eraRy``.
+-
+- Parameters
+- ----------
+- theta : double array
+- r : double array
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below. Note that, unlike the erfa routine,
+- the python wrapper does not change r in-place.
+-
+- - - - - - -
+- e r a R y
+- - - - - - -
+-
+- Rotate an r-matrix about the y-axis.
+-
+- Given:
+- theta double angle (radians)
+-
+- Given and returned:
+- r double[3][3] r-matrix, rotated
+-
+- Notes:
+-
+- 1) Calling this function with positive theta incorporates in the
+- supplied r-matrix r an additional rotation, about the y-axis,
+- anticlockwise as seen looking towards the origin from positive y.
+-
+- 2) The additional rotation can be represented by this matrix:
+-
+- ( + cos(theta) 0 - sin(theta) )
+- ( )
+- ( 0 1 0 )
+- ( )
+- ( + sin(theta) 0 + cos(theta) )
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.ry(theta, r)
+- return r
+-
+-
+-def rz(psi, r):
+- """
+- Wrapper for ERFA function ``eraRz``.
+-
+- Parameters
+- ----------
+- psi : double array
+- r : double array
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below. Note that, unlike the erfa routine,
+- the python wrapper does not change r in-place.
+-
+- - - - - - -
+- e r a R z
+- - - - - - -
+-
+- Rotate an r-matrix about the z-axis.
+-
+- Given:
+- psi double angle (radians)
+-
+- Given and returned:
+- r double[3][3] r-matrix, rotated
+-
+- Notes:
+-
+- 1) Calling this function with positive psi incorporates in the
+- supplied r-matrix r an additional rotation, about the z-axis,
+- anticlockwise as seen looking towards the origin from positive z.
+-
+- 2) The additional rotation can be represented by this matrix:
+-
+- ( + cos(psi) + sin(psi) 0 )
+- ( )
+- ( - sin(psi) + cos(psi) 0 )
+- ( )
+- ( 0 0 1 )
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.rz(psi, r)
+- return r
+-
+-
+-def cp(p):
+- """
+- Wrapper for ERFA function ``eraCp``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- c : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a C p
+- - - - - - -
+-
+- Copy a p-vector.
+-
+- Given:
+- p double[3] p-vector to be copied
+-
+- Returned:
+- c double[3] copy
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c = ufunc.cp(p)
+- return c
+-
+-
+-def cpv(pv):
+- """
+- Wrapper for ERFA function ``eraCpv``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- c : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a C p v
+- - - - - - - -
+-
+- Copy a position/velocity vector.
+-
+- Given:
+- pv double[2][3] position/velocity vector to be copied
+-
+- Returned:
+- c double[2][3] copy
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c = ufunc.cpv(pv)
+- return c
+-
+-
+-def cr(r):
+- """
+- Wrapper for ERFA function ``eraCr``.
+-
+- Parameters
+- ----------
+- r : double array
+-
+- Returns
+- -------
+- c : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a C r
+- - - - - - -
+-
+- Copy an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix to be copied
+-
+- Returned:
+- c double[3][3] copy
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c = ufunc.cr(r)
+- return c
+-
+-
+-def p2pv(p):
+- """
+- Wrapper for ERFA function ``eraP2pv``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P 2 p v
+- - - - - - - - -
+-
+- Extend a p-vector to a pv-vector by appending a zero velocity.
+-
+- Given:
+- p double[3] p-vector
+-
+- Returned:
+- pv double[2][3] pv-vector
+-
+- Called:
+- eraCp copy p-vector
+- eraZp zero p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv = ufunc.p2pv(p)
+- return pv
+-
+-
+-def pv2p(pv):
+- """
+- Wrapper for ERFA function ``eraPv2p``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- p : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P v 2 p
+- - - - - - - - -
+-
+- Discard velocity component of a pv-vector.
+-
+- Given:
+- pv double[2][3] pv-vector
+-
+- Returned:
+- p double[3] p-vector
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p = ufunc.pv2p(pv)
+- return p
+-
+-
+-def ir():
+- """
+- Wrapper for ERFA function ``eraIr``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a I r
+- - - - - - -
+-
+- Initialize an r-matrix to the identity matrix.
+-
+- Returned:
+- r double[3][3] r-matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.ir()
+- return r
+-
+-
+-def zp():
+- """
+- Wrapper for ERFA function ``eraZp``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- p : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a Z p
+- - - - - - -
+-
+- Zero a p-vector.
+-
+- Returned:
+- p double[3] p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p = ufunc.zp()
+- return p
+-
+-
+-def zpv():
+- """
+- Wrapper for ERFA function ``eraZpv``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a Z p v
+- - - - - - - -
+-
+- Zero a pv-vector.
+-
+- Returned:
+- pv double[2][3] pv-vector
+-
+- Called:
+- eraZp zero p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv = ufunc.zpv()
+- return pv
+-
+-
+-def zr():
+- """
+- Wrapper for ERFA function ``eraZr``.
+-
+- Parameters
+- ----------
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a Z r
+- - - - - - -
+-
+- Initialize an r-matrix to the null matrix.
+-
+- Returned:
+- r double[3][3] r-matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.zr()
+- return r
+-
+-
+-def rxr(a, b):
+- """
+- Wrapper for ERFA function ``eraRxr``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- atb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a R x r
+- - - - - - - -
+-
+- Multiply two r-matrices.
+-
+- Given:
+- a double[3][3] first r-matrix
+- b double[3][3] second r-matrix
+-
+- Returned:
+- atb double[3][3] a * b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Called:
+- eraCr copy r-matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- atb = ufunc.rxr(a, b)
+- return atb
+-
+-
+-def tr(r):
+- """
+- Wrapper for ERFA function ``eraTr``.
+-
+- Parameters
+- ----------
+- r : double array
+-
+- Returns
+- -------
+- rt : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a T r
+- - - - - - -
+-
+- Transpose an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix
+-
+- Returned:
+- rt double[3][3] transpose
+-
+- Note:
+- It is permissible for r and rt to be the same array.
+-
+- Called:
+- eraCr copy r-matrix
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rt = ufunc.tr(r)
+- return rt
+-
+-
+-def rxp(r, p):
+- """
+- Wrapper for ERFA function ``eraRxp``.
+-
+- Parameters
+- ----------
+- r : double array
+- p : double array
+-
+- Returns
+- -------
+- rp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a R x p
+- - - - - - - -
+-
+- Multiply a p-vector by an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix
+- p double[3] p-vector
+-
+- Returned:
+- rp double[3] r * p
+-
+- Note:
+- It is permissible for p and rp to be the same array.
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rp = ufunc.rxp(r, p)
+- return rp
+-
+-
+-def rxpv(r, pv):
+- """
+- Wrapper for ERFA function ``eraRxpv``.
+-
+- Parameters
+- ----------
+- r : double array
+- pv : double array
+-
+- Returns
+- -------
+- rpv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a R x p v
+- - - - - - - - -
+-
+- Multiply a pv-vector by an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix
+- pv double[2][3] pv-vector
+-
+- Returned:
+- rpv double[2][3] r * pv
+-
+- Note:
+- It is permissible for pv and rpv to be the same array.
+-
+- Called:
+- eraRxp product of r-matrix and p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- rpv = ufunc.rxpv(r, pv)
+- return rpv
+-
+-
+-def trxp(r, p):
+- """
+- Wrapper for ERFA function ``eraTrxp``.
+-
+- Parameters
+- ----------
+- r : double array
+- p : double array
+-
+- Returns
+- -------
+- trp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a T r x p
+- - - - - - - - -
+-
+- Multiply a p-vector by the transpose of an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix
+- p double[3] p-vector
+-
+- Returned:
+- trp double[3] r * p
+-
+- Note:
+- It is permissible for p and trp to be the same array.
+-
+- Called:
+- eraTr transpose r-matrix
+- eraRxp product of r-matrix and p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- trp = ufunc.trxp(r, p)
+- return trp
+-
+-
+-def trxpv(r, pv):
+- """
+- Wrapper for ERFA function ``eraTrxpv``.
+-
+- Parameters
+- ----------
+- r : double array
+- pv : double array
+-
+- Returns
+- -------
+- trpv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a T r x p v
+- - - - - - - - - -
+-
+- Multiply a pv-vector by the transpose of an r-matrix.
+-
+- Given:
+- r double[3][3] r-matrix
+- pv double[2][3] pv-vector
+-
+- Returned:
+- trpv double[2][3] r * pv
+-
+- Note:
+- It is permissible for pv and trpv to be the same array.
+-
+- Called:
+- eraTr transpose r-matrix
+- eraRxpv product of r-matrix and pv-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- trpv = ufunc.trxpv(r, pv)
+- return trpv
+-
+-
+-def rm2v(r):
+- """
+- Wrapper for ERFA function ``eraRm2v``.
+-
+- Parameters
+- ----------
+- r : double array
+-
+- Returns
+- -------
+- w : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a R m 2 v
+- - - - - - - - -
+-
+- Express an r-matrix as an r-vector.
+-
+- Given:
+- r double[3][3] rotation matrix
+-
+- Returned:
+- w double[3] rotation vector (Note 1)
+-
+- Notes:
+-
+- 1) A rotation matrix describes a rotation through some angle about
+- some arbitrary axis called the Euler axis. The "rotation vector"
+- returned by this function has the same direction as the Euler axis,
+- and its magnitude is the angle in radians. (The magnitude and
+- direction can be separated by means of the function eraPn.)
+-
+- 2) If r is null, so is the result. If r is not a rotation matrix
+- the result is undefined; r must be proper (i.e. have a positive
+- determinant) and real orthogonal (inverse = transpose).
+-
+- 3) The reference frame rotates clockwise as seen looking along
+- the rotation vector from the origin.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- w = ufunc.rm2v(r)
+- return w
+-
+-
+-def rv2m(w):
+- """
+- Wrapper for ERFA function ``eraRv2m``.
+-
+- Parameters
+- ----------
+- w : double array
+-
+- Returns
+- -------
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a R v 2 m
+- - - - - - - - -
+-
+- Form the r-matrix corresponding to a given r-vector.
+-
+- Given:
+- w double[3] rotation vector (Note 1)
+-
+- Returned:
+- r double[3][3] rotation matrix
+-
+- Notes:
+-
+- 1) A rotation matrix describes a rotation through some angle about
+- some arbitrary axis called the Euler axis. The "rotation vector"
+- supplied to This function has the same direction as the Euler
+- axis, and its magnitude is the angle in radians.
+-
+- 2) If w is null, the unit matrix is returned.
+-
+- 3) The reference frame rotates clockwise as seen looking along the
+- rotation vector from the origin.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r = ufunc.rv2m(w)
+- return r
+-
+-
+-def pap(a, b):
+- """
+- Wrapper for ERFA function ``eraPap``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P a p
+- - - - - - - -
+-
+- Position-angle from two p-vectors.
+-
+- Given:
+- a double[3] direction of reference point
+- b double[3] direction of point whose PA is required
+-
+- Returned (function value):
+- double position angle of b with respect to a (radians)
+-
+- Notes:
+-
+- 1) The result is the position angle, in radians, of direction b with
+- respect to direction a. It is in the range -pi to +pi. The
+- sense is such that if b is a small distance "north" of a the
+- position angle is approximately zero, and if b is a small
+- distance "east" of a the position angle is approximately +pi/2.
+-
+- 2) The vectors a and b need not be of unit length.
+-
+- 3) Zero is returned if the two directions are the same or if either
+- vector is null.
+-
+- 4) If vector a is at a pole, the result is ill-defined.
+-
+- Called:
+- eraPn decompose p-vector into modulus and direction
+- eraPm modulus of p-vector
+- eraPxp vector product of two p-vectors
+- eraPmp p-vector minus p-vector
+- eraPdp scalar product of two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.pap(a, b)
+- return c_retval
+-
+-
+-def pas(al, ap, bl, bp):
+- """
+- Wrapper for ERFA function ``eraPas``.
+-
+- Parameters
+- ----------
+- al : double array
+- ap : double array
+- bl : double array
+- bp : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P a s
+- - - - - - - -
+-
+- Position-angle from spherical coordinates.
+-
+- Given:
+- al double longitude of point A (e.g. RA) in radians
+- ap double latitude of point A (e.g. Dec) in radians
+- bl double longitude of point B
+- bp double latitude of point B
+-
+- Returned (function value):
+- double position angle of B with respect to A
+-
+- Notes:
+-
+- 1) The result is the bearing (position angle), in radians, of point
+- B with respect to point A. It is in the range -pi to +pi. The
+- sense is such that if B is a small distance "east" of point A,
+- the bearing is approximately +pi/2.
+-
+- 2) Zero is returned if the two points are coincident.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.pas(al, ap, bl, bp)
+- return c_retval
+-
+-
+-def sepp(a, b):
+- """
+- Wrapper for ERFA function ``eraSepp``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S e p p
+- - - - - - - - -
+-
+- Angular separation between two p-vectors.
+-
+- Given:
+- a double[3] first p-vector (not necessarily unit length)
+- b double[3] second p-vector (not necessarily unit length)
+-
+- Returned (function value):
+- double angular separation (radians, always positive)
+-
+- Notes:
+-
+- 1) If either vector is null, a zero result is returned.
+-
+- 2) The angular separation is most simply formulated in terms of
+- scalar product. However, this gives poor accuracy for angles
+- near zero and pi. The present algorithm uses both cross product
+- and dot product, to deliver full accuracy whatever the size of
+- the angle.
+-
+- Called:
+- eraPxp vector product of two p-vectors
+- eraPm modulus of p-vector
+- eraPdp scalar product of two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.sepp(a, b)
+- return c_retval
+-
+-
+-def seps(al, ap, bl, bp):
+- """
+- Wrapper for ERFA function ``eraSeps``.
+-
+- Parameters
+- ----------
+- al : double array
+- ap : double array
+- bl : double array
+- bp : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S e p s
+- - - - - - - - -
+-
+- Angular separation between two sets of spherical coordinates.
+-
+- Given:
+- al double first longitude (radians)
+- ap double first latitude (radians)
+- bl double second longitude (radians)
+- bp double second latitude (radians)
+-
+- Returned (function value):
+- double angular separation (radians)
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraSepp angular separation between two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.seps(al, ap, bl, bp)
+- return c_retval
+-
+-
+-def c2s(p):
+- """
+- Wrapper for ERFA function ``eraC2s``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- theta : double array
+- phi : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a C 2 s
+- - - - - - - -
+-
+- P-vector to spherical coordinates.
+-
+- Given:
+- p double[3] p-vector
+-
+- Returned:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+-
+- Notes:
+-
+- 1) The vector p can have any magnitude; only its direction is used.
+-
+- 2) If p is null, zero theta and phi are returned.
+-
+- 3) At either pole, zero theta is returned.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- theta, phi = ufunc.c2s(p)
+- return theta, phi
+-
+-
+-def p2s(p):
+- """
+- Wrapper for ERFA function ``eraP2s``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- theta : double array
+- phi : double array
+- r : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P 2 s
+- - - - - - - -
+-
+- P-vector to spherical polar coordinates.
+-
+- Given:
+- p double[3] p-vector
+-
+- Returned:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+- r double radial distance
+-
+- Notes:
+-
+- 1) If P is null, zero theta, phi and r are returned.
+-
+- 2) At either pole, zero theta is returned.
+-
+- Called:
+- eraC2s p-vector to spherical
+- eraPm modulus of p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- theta, phi, r = ufunc.p2s(p)
+- return theta, phi, r
+-
+-
+-def pv2s(pv):
+- """
+- Wrapper for ERFA function ``eraPv2s``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- theta : double array
+- phi : double array
+- r : double array
+- td : double array
+- pd : double array
+- rd : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P v 2 s
+- - - - - - - - -
+-
+- Convert position/velocity from Cartesian to spherical coordinates.
+-
+- Given:
+- pv double[2][3] pv-vector
+-
+- Returned:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+- r double radial distance
+- td double rate of change of theta
+- pd double rate of change of phi
+- rd double rate of change of r
+-
+- Notes:
+-
+- 1) If the position part of pv is null, theta, phi, td and pd
+- are indeterminate. This is handled by extrapolating the
+- position through unit time by using the velocity part of
+- pv. This moves the origin without changing the direction
+- of the velocity component. If the position and velocity
+- components of pv are both null, zeroes are returned for all
+- six results.
+-
+- 2) If the position is a pole, theta, td and pd are indeterminate.
+- In such cases zeroes are returned for all three.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- theta, phi, r, td, pd, rd = ufunc.pv2s(pv)
+- return theta, phi, r, td, pd, rd
+-
+-
+-def s2c(theta, phi):
+- """
+- Wrapper for ERFA function ``eraS2c``.
+-
+- Parameters
+- ----------
+- theta : double array
+- phi : double array
+-
+- Returns
+- -------
+- c : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a S 2 c
+- - - - - - - -
+-
+- Convert spherical coordinates to Cartesian.
+-
+- Given:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+-
+- Returned:
+- c double[3] direction cosines
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c = ufunc.s2c(theta, phi)
+- return c
+-
+-
+-def s2p(theta, phi, r):
+- """
+- Wrapper for ERFA function ``eraS2p``.
+-
+- Parameters
+- ----------
+- theta : double array
+- phi : double array
+- r : double array
+-
+- Returns
+- -------
+- p : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a S 2 p
+- - - - - - - -
+-
+- Convert spherical polar coordinates to p-vector.
+-
+- Given:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+- r double radial distance
+-
+- Returned:
+- p double[3] Cartesian coordinates
+-
+- Called:
+- eraS2c spherical coordinates to unit vector
+- eraSxp multiply p-vector by scalar
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p = ufunc.s2p(theta, phi, r)
+- return p
+-
+-
+-def s2pv(theta, phi, r, td, pd, rd):
+- """
+- Wrapper for ERFA function ``eraS2pv``.
+-
+- Parameters
+- ----------
+- theta : double array
+- phi : double array
+- r : double array
+- td : double array
+- pd : double array
+- rd : double array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S 2 p v
+- - - - - - - - -
+-
+- Convert position/velocity from spherical to Cartesian coordinates.
+-
+- Given:
+- theta double longitude angle (radians)
+- phi double latitude angle (radians)
+- r double radial distance
+- td double rate of change of theta
+- pd double rate of change of phi
+- rd double rate of change of r
+-
+- Returned:
+- pv double[2][3] pv-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv = ufunc.s2pv(theta, phi, r, td, pd, rd)
+- return pv
+-
+-
+-def pdp(a, b):
+- """
+- Wrapper for ERFA function ``eraPdp``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P d p
+- - - - - - - -
+-
+- p-vector inner (=scalar=dot) product.
+-
+- Given:
+- a double[3] first p-vector
+- b double[3] second p-vector
+-
+- Returned (function value):
+- double a . b
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.pdp(a, b)
+- return c_retval
+-
+-
+-def pm(p):
+- """
+- Wrapper for ERFA function ``eraPm``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- c_retval : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a P m
+- - - - - - -
+-
+- Modulus of p-vector.
+-
+- Given:
+- p double[3] p-vector
+-
+- Returned (function value):
+- double modulus
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- c_retval = ufunc.pm(p)
+- return c_retval
+-
+-
+-def pmp(a, b):
+- """
+- Wrapper for ERFA function ``eraPmp``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- amb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P m p
+- - - - - - - -
+-
+- P-vector subtraction.
+-
+- Given:
+- a double[3] first p-vector
+- b double[3] second p-vector
+-
+- Returned:
+- amb double[3] a - b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- amb = ufunc.pmp(a, b)
+- return amb
+-
+-
+-def pn(p):
+- """
+- Wrapper for ERFA function ``eraPn``.
+-
+- Parameters
+- ----------
+- p : double array
+-
+- Returns
+- -------
+- r : double array
+- u : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - -
+- e r a P n
+- - - - - - -
+-
+- Convert a p-vector into modulus and unit vector.
+-
+- Given:
+- p double[3] p-vector
+-
+- Returned:
+- r double modulus
+- u double[3] unit vector
+-
+- Notes:
+-
+- 1) If p is null, the result is null. Otherwise the result is a unit
+- vector.
+-
+- 2) It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Called:
+- eraPm modulus of p-vector
+- eraZp zero p-vector
+- eraSxp multiply p-vector by scalar
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r, u = ufunc.pn(p)
+- return r, u
+-
+-
+-def ppp(a, b):
+- """
+- Wrapper for ERFA function ``eraPpp``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- apb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P p p
+- - - - - - - -
+-
+- P-vector addition.
+-
+- Given:
+- a double[3] first p-vector
+- b double[3] second p-vector
+-
+- Returned:
+- apb double[3] a + b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- apb = ufunc.ppp(a, b)
+- return apb
+-
+-
+-def ppsp(a, s, b):
+- """
+- Wrapper for ERFA function ``eraPpsp``.
+-
+- Parameters
+- ----------
+- a : double array
+- s : double array
+- b : double array
+-
+- Returns
+- -------
+- apsb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P p s p
+- - - - - - - - -
+-
+- P-vector plus scaled p-vector.
+-
+- Given:
+- a double[3] first p-vector
+- s double scalar (multiplier for b)
+- b double[3] second p-vector
+-
+- Returned:
+- apsb double[3] a + s*b
+-
+- Note:
+- It is permissible for any of a, b and apsb to be the same array.
+-
+- Called:
+- eraSxp multiply p-vector by scalar
+- eraPpp p-vector plus p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- apsb = ufunc.ppsp(a, s, b)
+- return apsb
+-
+-
+-def pvdpv(a, b):
+- """
+- Wrapper for ERFA function ``eraPvdpv``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- adb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v d p v
+- - - - - - - - - -
+-
+- Inner (=scalar=dot) product of two pv-vectors.
+-
+- Given:
+- a double[2][3] first pv-vector
+- b double[2][3] second pv-vector
+-
+- Returned:
+- adb double[2] a . b (see note)
+-
+- Note:
+-
+- If the position and velocity components of the two pv-vectors are
+- ( ap, av ) and ( bp, bv ), the result, a . b, is the pair of
+- numbers ( ap . bp , ap . bv + av . bp ). The two numbers are the
+- dot-product of the two p-vectors and its derivative.
+-
+- Called:
+- eraPdp scalar product of two p-vectors
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- adb = ufunc.pvdpv(a, b)
+- return adb
+-
+-
+-def pvm(pv):
+- """
+- Wrapper for ERFA function ``eraPvm``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- r : double array
+- s : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P v m
+- - - - - - - -
+-
+- Modulus of pv-vector.
+-
+- Given:
+- pv double[2][3] pv-vector
+-
+- Returned:
+- r double modulus of position component
+- s double modulus of velocity component
+-
+- Called:
+- eraPm modulus of p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- r, s = ufunc.pvm(pv)
+- return r, s
+-
+-
+-def pvmpv(a, b):
+- """
+- Wrapper for ERFA function ``eraPvmpv``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- amb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v m p v
+- - - - - - - - - -
+-
+- Subtract one pv-vector from another.
+-
+- Given:
+- a double[2][3] first pv-vector
+- b double[2][3] second pv-vector
+-
+- Returned:
+- amb double[2][3] a - b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Called:
+- eraPmp p-vector minus p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- amb = ufunc.pvmpv(a, b)
+- return amb
+-
+-
+-def pvppv(a, b):
+- """
+- Wrapper for ERFA function ``eraPvppv``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- apb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v p p v
+- - - - - - - - - -
+-
+- Add one pv-vector to another.
+-
+- Given:
+- a double[2][3] first pv-vector
+- b double[2][3] second pv-vector
+-
+- Returned:
+- apb double[2][3] a + b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Called:
+- eraPpp p-vector plus p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- apb = ufunc.pvppv(a, b)
+- return apb
+-
+-
+-def pvu(dt, pv):
+- """
+- Wrapper for ERFA function ``eraPvu``.
+-
+- Parameters
+- ----------
+- dt : double array
+- pv : double array
+-
+- Returns
+- -------
+- upv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P v u
+- - - - - - - -
+-
+- Update a pv-vector.
+-
+- Given:
+- dt double time interval
+- pv double[2][3] pv-vector
+-
+- Returned:
+- upv double[2][3] p updated, v unchanged
+-
+- Notes:
+-
+- 1) "Update" means "refer the position component of the vector
+- to a new date dt time units from the existing date".
+-
+- 2) The time units of dt must match those of the velocity.
+-
+- 3) It is permissible for pv and upv to be the same array.
+-
+- Called:
+- eraPpsp p-vector plus scaled p-vector
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- upv = ufunc.pvu(dt, pv)
+- return upv
+-
+-
+-def pvup(dt, pv):
+- """
+- Wrapper for ERFA function ``eraPvup``.
+-
+- Parameters
+- ----------
+- dt : double array
+- pv : double array
+-
+- Returns
+- -------
+- p : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a P v u p
+- - - - - - - - -
+-
+- Update a pv-vector, discarding the velocity component.
+-
+- Given:
+- dt double time interval
+- pv double[2][3] pv-vector
+-
+- Returned:
+- p double[3] p-vector
+-
+- Notes:
+-
+- 1) "Update" means "refer the position component of the vector to a
+- new date dt time units from the existing date".
+-
+- 2) The time units of dt must match those of the velocity.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p = ufunc.pvup(dt, pv)
+- return p
+-
+-
+-def pvxpv(a, b):
+- """
+- Wrapper for ERFA function ``eraPvxpv``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- axb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v x p v
+- - - - - - - - - -
+-
+- Outer (=vector=cross) product of two pv-vectors.
+-
+- Given:
+- a double[2][3] first pv-vector
+- b double[2][3] second pv-vector
+-
+- Returned:
+- axb double[2][3] a x b
+-
+- Notes:
+-
+- 1) If the position and velocity components of the two pv-vectors are
+- ( ap, av ) and ( bp, bv ), the result, a x b, is the pair of
+- vectors ( ap x bp, ap x bv + av x bp ). The two vectors are the
+- cross-product of the two p-vectors and its derivative.
+-
+- 2) It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Called:
+- eraCpv copy pv-vector
+- eraPxp vector product of two p-vectors
+- eraPpp p-vector plus p-vector
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- axb = ufunc.pvxpv(a, b)
+- return axb
+-
+-
+-def pxp(a, b):
+- """
+- Wrapper for ERFA function ``eraPxp``.
+-
+- Parameters
+- ----------
+- a : double array
+- b : double array
+-
+- Returns
+- -------
+- axb : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a P x p
+- - - - - - - -
+-
+- p-vector outer (=vector=cross) product.
+-
+- Given:
+- a double[3] first p-vector
+- b double[3] second p-vector
+-
+- Returned:
+- axb double[3] a x b
+-
+- Note:
+- It is permissible to re-use the same array for any of the
+- arguments.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- axb = ufunc.pxp(a, b)
+- return axb
+-
+-
+-def s2xpv(s1, s2, pv):
+- """
+- Wrapper for ERFA function ``eraS2xpv``.
+-
+- Parameters
+- ----------
+- s1 : double array
+- s2 : double array
+- pv : double array
+-
+- Returns
+- -------
+- spv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a S 2 x p v
+- - - - - - - - - -
+-
+- Multiply a pv-vector by two scalars.
+-
+- Given:
+- s1 double scalar to multiply position component by
+- s2 double scalar to multiply velocity component by
+- pv double[2][3] pv-vector
+-
+- Returned:
+- spv double[2][3] pv-vector: p scaled by s1, v scaled by s2
+-
+- Note:
+- It is permissible for pv and spv to be the same array.
+-
+- Called:
+- eraSxp multiply p-vector by scalar
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- spv = ufunc.s2xpv(s1, s2, pv)
+- return spv
+-
+-
+-def sxp(s, p):
+- """
+- Wrapper for ERFA function ``eraSxp``.
+-
+- Parameters
+- ----------
+- s : double array
+- p : double array
+-
+- Returns
+- -------
+- sp : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - -
+- e r a S x p
+- - - - - - - -
+-
+- Multiply a p-vector by a scalar.
+-
+- Given:
+- s double scalar
+- p double[3] p-vector
+-
+- Returned:
+- sp double[3] s * p
+-
+- Note:
+- It is permissible for p and sp to be the same array.
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- sp = ufunc.sxp(s, p)
+- return sp
+-
+-
+-def sxpv(s, pv):
+- """
+- Wrapper for ERFA function ``eraSxpv``.
+-
+- Parameters
+- ----------
+- s : double array
+- pv : double array
+-
+- Returns
+- -------
+- spv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - -
+- e r a S x p v
+- - - - - - - - -
+-
+- Multiply a pv-vector by a scalar.
+-
+- Given:
+- s double scalar
+- pv double[2][3] pv-vector
+-
+- Returned:
+- spv double[2][3] s * pv
+-
+- Note:
+- It is permissible for pv and spv to be the same array
+-
+- Called:
+- eraS2xpv multiply pv-vector by two scalars
+-
+- Copyright (C) 2013-2019, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- spv = ufunc.sxpv(s, pv)
+- return spv
+-
+-
+-def pav2pv(p, v):
+- """
+- Wrapper for ERFA function ``eraPav2pv``.
+-
+- Parameters
+- ----------
+- p : double array
+- v : double array
+-
+- Returns
+- -------
+- pv : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - - -
+- e r a P a v 2 p v
+- - - - - - - - - - -
+-
+- Extend a p-vector to a pv-vector by appending a zero velocity.
+-
+- Given:
+- p double[3] p-vector
+- v double[3] v-vector
+-
+- Returned:
+- pv double[2][3] pv-vector
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2017, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- pv = ufunc.pav2pv(p, v)
+- return pv
+-
+-
+-def pv2pav(pv):
+- """
+- Wrapper for ERFA function ``eraPv2pav``.
+-
+- Parameters
+- ----------
+- pv : double array
+-
+- Returns
+- -------
+- p : double array
+- v : double array
+-
+- Notes
+- -----
+- The ERFA documentation is below.
+-
+- - - - - - - - - -
+- e r a P v 2 p a v
+- - - - - - - - - -
+-
+- Extend a p-vector to a pv-vector by appending a zero velocity.
+-
+- Given:
+- pv double[2][3] pv-vector
+-
+- Returned:
+- p double[3] p-vector
+- v double[3] v-vector
+-
+- Called:
+- eraCp copy p-vector
+-
+- Copyright (C) 2013-2017, NumFOCUS Foundation.
+- Derived, with permission, from the SOFA library. See notes at end of file.
+-
+- """
+- p, v = ufunc.pv2pav(pv)
+- return p, v
+-
+-
+-# TODO: delete the functions below when they can get auto-generated
+-# (current machinery doesn't support returning strings or non-status-codes)
+-def version():
+- """
+- Returns the package version
+- as defined in configure.ac
+- in string format
+- """
+- return "1.6.0"
+-
+-
+-def version_major():
+- """
+- Returns the package major version
+- as defined in configure.ac
+- as integer
+- """
+- return 1
+-
+-
+-def version_minor():
+- """
+- Returns the package minor version
+- as defined in configure.ac
+- as integer
+- """
+- return 6
+-
+-
+-def version_micro():
+- """
+- Returns the package micro version
+- as defined in configure.ac
+- as integer
+- """
+- return 0
+-
+-
+-def sofa_version():
+- """
+- Returns the corresponding SOFA version
+- as defined in configure.ac
+- in string format
+- """
+- return "20190722"
+\ No newline at end of file
+Index: astropy-4.1/astropy/_erfa/ufunc.c
+===================================================================
+--- astropy-4.1.orig/astropy/_erfa/ufunc.c
++++ /dev/null
+@@ -1,14016 +0,0 @@
+-/* -*- mode: c -*- */
+-
+-/* Licensed under a 3-clause BSD style license - see LICENSE.rst */
+-
+-/*
+- * "ufunc.c" is auto-generated by erfa_generator.py from the template
+- * "ufunc.c.templ". Do *not* edit "ufunc.c" directly, instead edit
+- * "ufunc.c.templ" and run ufunc_generator.py from the source directory
+- * to update it.
+- */
+-
+-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+-#include "Python.h"
+-#include "numpy/arrayobject.h"
+-#include "numpy/ufuncobject.h"
+-#include "erfa.h"
+-#include "erfaextra.h"
+-#include "erfa_additions.h"
+-
+-#define MODULE_DOCSTRING \
+- "Ufunc wrappers of the ERFA routines.\n\n" \
+- "These ufuncs vectorize the ERFA functions assuming structured dtypes\n" \
+- "for vector and matrix arguments. Status codes are vectors as well.\n" \
+- "Python wrappers are also provided, which convert between\n" \
+- "trailing dimensions and structured dtypes where necessary,\n" \
+- "and combine status codes."
+-#define GET_LEAP_SECONDS_DOCSTRING \
+- "get_leap_seconds()\n\n" \
+- "Access the leap second table used in ERFA.\n\n" \
+- "Returns\n" \
+- "-------\n" \
+- "leap_seconds : `~numpy.ndarray`\n" \
+- " With structured dtype `~astropy._erfa.dt_eraLEAPSECOND`,\n" \
+- " containing items 'year', 'month', and 'tai_utc'."
+-#define SET_LEAP_SECONDS_DOCSTRING \
+- "set_leap_seconds([table])\n\n" \
+- "Set the leap second table used in ERFA.\n\n" \
+- "Parameters\n" \
+- "----------\n" \
+- "leap_seconds : array_like, optional\n" \
+- " With structured dtype `~astropy._erfa.dt_eraLEAPSECOND`,\n" \
+- " containing items 'year', 'month', and 'tai_utc'.\n" \
+- " If not given, reset to the ERFA built-in table.\n\n" \
+- "Notes\n" \
+- "-----\n" \
+- "No sanity checks are done on the input; it is simply coerced\n" \
+- "to the correct dtype."
+-
+-
+-static inline void copy_to_double3(char *ptr, npy_intp s, double d[3]) {
+- char *p = ptr;
+- int j;
+- for (j = 0; j < 3; j++, p += s) {
+- d[j] = *(double *)p;
+- }
+-}
+-
+-static inline void copy_from_double3(char *ptr, npy_intp s, double d[3]) {
+- char *p = ptr;
+- int j;
+- for (j = 0; j < 3; j++, p += s) {
+- *(double *)p = d[j];
+- }
+-}
+-
+-static inline void copy_to_double33(char *ptr, npy_intp s0, npy_intp s1,
+- double d[3][3]) {
+- char *p0 = ptr;
+- int j0, j1;
+- for (j0 = 0; j0 < 3; j0++, p0 += s0) {
+- char *p1 = p0;
+- for (j1 = 0; j1 < 3; j1++, p1 += s1) {
+- d[j0][j1] = *(double *)p1;
+- }
+- }
+-}
+-
+-static inline void copy_from_double33(char *ptr, npy_intp s0, npy_intp s1,
+- double d[3][3]) {
+- char *p = ptr;
+- char *p0 = ptr;
+- int j0, j1;
+- for (j0 = 0; j0 < 3; j0++, p0 += s0) {
+- char *p1 = p0;
+- for (j1 = 0; j1 < 3; j1++, p1 += s1) {
+- *(double *)p = d[j0][j1];
+- }
+- }
+-}
+-
+-/* eraLDBODY is never returned, so we do not need a copy_from */
+-static inline void copy_to_eraLDBODY(char *ptr, npy_intp s, npy_intp n,
+- eraLDBODY b[]) {
+- char *p = ptr;
+- npy_intp j;
+- for (j = 0; j < n; j++, p += s) {
+- b[j] = *(eraLDBODY *)p;
+- }
+-}
+-
+-/*
+- * INNER LOOPS - iteratively call the erfa function for a chunk of data.
+- *
+- * For each argument:
+- * char * is the pointer to the data in memory;
+- * npy_intp s_ is the number of bytes between successive elements;
+- * *_ is a correctly cast pointer to the current element;
+- * ( _, i.e., not a pointer, for status codes and return values)
+- *
+- * Notes:
+- * 1. Some erfa function change elements in-place; in the ufunc, these "inout"
+- * arguments are treated as separate: data is copied from the input to the
+- * output, and the output is changed in-place by the erfa function.
+- * To reproduce the in-place behaviour, the input to the ufunc can be passed
+- * in as output as well -- as is done in the python wrapper (the copy will
+- * be omitted for this case).
+- * 2. Any erfa function involving light deflection requires an struct
+- * eraLDBODY argument with a dimension that is user-defined. Those function
+- * are implemented as generalized ufuncs, with a signature in which the
+- * relevant variable is marked (i.e., '(),...,(n), (), ... -> (),...').
+- * In the inner loops, an appropriate copy is done if in the numpy array
+- * the n elements are not contiguous.
+- * 3. Similar copies are done for erfa functions that require vectors or
+- * matrices, if the corresponding axes in the input or output operands are
+- * not contiguous.
+- */
+-
+-static void ufunc_loop_cal2jd(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *iy = *args++;
+- npy_intp s_iy = *steps++;
+- char *im = *args++;
+- npy_intp s_im = *steps++;
+- char *id = *args++;
+- npy_intp s_id = *steps++;
+- char *djm0 = *args++;
+- npy_intp s_djm0 = *steps++;
+- char *djm = *args++;
+- npy_intp s_djm = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_iy);
+- int (*_im);
+- int (*_id);
+- double (*_djm0);
+- double (*_djm);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, iy += s_iy, im += s_im, id += s_id, djm0 += s_djm0, djm += s_djm, c_retval += s_c_retval) {
+- _iy = ((int (*))iy);
+- _im = ((int (*))im);
+- _id = ((int (*))id);
+- _djm0 = ((double (*))djm0);
+- _djm = ((double (*))djm);
+- _c_retval = eraCal2jd(*_iy, *_im, *_id, _djm0, _djm);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_epb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_dj1);
+- double (*_dj2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, dj1 += s_dj1, dj2 += s_dj2, c_retval += s_c_retval) {
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _c_retval = eraEpb(*_dj1, *_dj2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_epb2jd(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epb = *args++;
+- npy_intp s_epb = *steps++;
+- char *djm0 = *args++;
+- npy_intp s_djm0 = *steps++;
+- char *djm = *args++;
+- npy_intp s_djm = *steps++;
+- double (*_epb);
+- double (*_djm0);
+- double (*_djm);
+- for (i_o = 0; i_o < n_o;
+- i_o++, epb += s_epb, djm0 += s_djm0, djm += s_djm) {
+- _epb = ((double (*))epb);
+- _djm0 = ((double (*))djm0);
+- _djm = ((double (*))djm);
+- eraEpb2jd(*_epb, _djm0, _djm);
+- }
+-}
+-
+-static void ufunc_loop_epj(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_dj1);
+- double (*_dj2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, dj1 += s_dj1, dj2 += s_dj2, c_retval += s_c_retval) {
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _c_retval = eraEpj(*_dj1, *_dj2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_epj2jd(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *djm0 = *args++;
+- npy_intp s_djm0 = *steps++;
+- char *djm = *args++;
+- npy_intp s_djm = *steps++;
+- double (*_epj);
+- double (*_djm0);
+- double (*_djm);
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, djm0 += s_djm0, djm += s_djm) {
+- _epj = ((double (*))epj);
+- _djm0 = ((double (*))djm0);
+- _djm = ((double (*))djm);
+- eraEpj2jd(*_epj, _djm0, _djm);
+- }
+-}
+-
+-static void ufunc_loop_jd2cal(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *iy = *args++;
+- npy_intp s_iy = *steps++;
+- char *im = *args++;
+- npy_intp s_im = *steps++;
+- char *id = *args++;
+- npy_intp s_id = *steps++;
+- char *fd = *args++;
+- npy_intp s_fd = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_dj1);
+- double (*_dj2);
+- int (*_iy);
+- int (*_im);
+- int (*_id);
+- double (*_fd);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, dj1 += s_dj1, dj2 += s_dj2, iy += s_iy, im += s_im, id += s_id, fd += s_fd, c_retval += s_c_retval) {
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _iy = ((int (*))iy);
+- _im = ((int (*))im);
+- _id = ((int (*))id);
+- _fd = ((double (*))fd);
+- _c_retval = eraJd2cal(*_dj1, *_dj2, _iy, _im, _id, _fd);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_jdcalf(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ndp = *args++;
+- npy_intp s_ndp = *steps++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *iymdf = *args++;
+- npy_intp s_iymdf = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_ndp);
+- double (*_dj1);
+- double (*_dj2);
+- int (*_iymdf)[4];
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ndp += s_ndp, dj1 += s_dj1, dj2 += s_dj2, iymdf += s_iymdf, c_retval += s_c_retval) {
+- _ndp = ((int (*))ndp);
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _iymdf = ((int (*)[4])iymdf);
+- _c_retval = eraJdcalf(*_ndp, *_dj1, *_dj2, *_iymdf);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ab(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pnat = *args++;
+- npy_intp s_pnat = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *bm1 = *args++;
+- npy_intp s_bm1 = *steps++;
+- char *ppr = *args++;
+- npy_intp s_ppr = *steps++;
+- double b_pnat[3];
+- double (*_pnat)[3] = &b_pnat;
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- double (*_s);
+- double (*_bm1);
+- double b_ppr[3];
+- double (*_ppr)[3] = &b_ppr;
+- npy_intp is_pnat0 = *steps++;
+- int copy_pnat = (is_pnat0 != sizeof(double));
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- npy_intp is_ppr0 = *steps++;
+- int copy_ppr = (is_ppr0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, pnat += s_pnat, v += s_v, s += s_s, bm1 += s_bm1, ppr += s_ppr) {
+- if (copy_pnat) {
+- copy_to_double3(pnat, is_pnat0, *_pnat);
+- }
+- else {
+- _pnat = ((double (*)[3])pnat);
+- }
+- if (copy_v) {
+- copy_to_double3(v, is_v0, *_v);
+- }
+- else {
+- _v = ((double (*)[3])v);
+- }
+- _s = ((double (*))s);
+- _bm1 = ((double (*))bm1);
+- if (!copy_ppr) {
+- _ppr = ((double (*)[3])ppr);
+- }
+- eraAb(*_pnat, *_v, *_s, *_bm1, *_ppr);
+- if (copy_ppr) {
+- copy_from_double3(ppr, is_ppr0, *_ppr);
+- }
+- }
+-}
+-
+-static void ufunc_loop_apcg(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *ebpv = *args++;
+- npy_intp s_ebpv = *steps++;
+- char *ehp = *args++;
+- npy_intp s_ehp = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_ebpv)[2][3];
+- double b_ehp[3];
+- double (*_ehp)[3] = &b_ehp;
+- eraASTROM (*_astrom);
+- npy_intp is_ehp0 = *steps++;
+- int copy_ehp = (is_ehp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, ebpv += s_ebpv, ehp += s_ehp, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _ebpv = ((double (*)[2][3])ebpv);
+- if (copy_ehp) {
+- copy_to_double3(ehp, is_ehp0, *_ehp);
+- }
+- else {
+- _ehp = ((double (*)[3])ehp);
+- }
+- _astrom = ((eraASTROM (*))astrom);
+- eraApcg(*_date1, *_date2, *_ebpv, *_ehp, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apcg13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- eraASTROM (*_astrom);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _astrom = ((eraASTROM (*))astrom);
+- eraApcg13(*_date1, *_date2, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apci(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *ebpv = *args++;
+- npy_intp s_ebpv = *steps++;
+- char *ehp = *args++;
+- npy_intp s_ehp = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_ebpv)[2][3];
+- double b_ehp[3];
+- double (*_ehp)[3] = &b_ehp;
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- eraASTROM (*_astrom);
+- npy_intp is_ehp0 = *steps++;
+- int copy_ehp = (is_ehp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, ebpv += s_ebpv, ehp += s_ehp, x += s_x, y += s_y, s += s_s, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _ebpv = ((double (*)[2][3])ebpv);
+- if (copy_ehp) {
+- copy_to_double3(ehp, is_ehp0, *_ehp);
+- }
+- else {
+- _ehp = ((double (*)[3])ehp);
+- }
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- _astrom = ((eraASTROM (*))astrom);
+- eraApci(*_date1, *_date2, *_ebpv, *_ehp, *_x, *_y, *_s, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apci13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *eo = *args++;
+- npy_intp s_eo = *steps++;
+- double (*_date1);
+- double (*_date2);
+- eraASTROM (*_astrom);
+- double (*_eo);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, astrom += s_astrom, eo += s_eo) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _astrom = ((eraASTROM (*))astrom);
+- _eo = ((double (*))eo);
+- eraApci13(*_date1, *_date2, _astrom, _eo);
+- }
+-}
+-
+-static void ufunc_loop_apco(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *ebpv = *args++;
+- npy_intp s_ebpv = *steps++;
+- char *ehp = *args++;
+- npy_intp s_ehp = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *sp = *args++;
+- npy_intp s_sp = *steps++;
+- char *refa = *args++;
+- npy_intp s_refa = *steps++;
+- char *refb = *args++;
+- npy_intp s_refb = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_ebpv)[2][3];
+- double b_ehp[3];
+- double (*_ehp)[3] = &b_ehp;
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- double (*_theta);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_sp);
+- double (*_refa);
+- double (*_refb);
+- eraASTROM (*_astrom);
+- npy_intp is_ehp0 = *steps++;
+- int copy_ehp = (is_ehp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, ebpv += s_ebpv, ehp += s_ehp, x += s_x, y += s_y, s += s_s, theta += s_theta, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, sp += s_sp, refa += s_refa, refb += s_refb, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _ebpv = ((double (*)[2][3])ebpv);
+- if (copy_ehp) {
+- copy_to_double3(ehp, is_ehp0, *_ehp);
+- }
+- else {
+- _ehp = ((double (*)[3])ehp);
+- }
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- _theta = ((double (*))theta);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _sp = ((double (*))sp);
+- _refa = ((double (*))refa);
+- _refb = ((double (*))refb);
+- _astrom = ((eraASTROM (*))astrom);
+- eraApco(*_date1, *_date2, *_ebpv, *_ehp, *_x, *_y, *_s, *_theta, *_elong, *_phi, *_hm, *_xp, *_yp, *_sp, *_refa, *_refb, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apco13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *eo = *args++;
+- npy_intp s_eo = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- eraASTROM (*_astrom);
+- double (*_eo);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, astrom += s_astrom, eo += s_eo, c_retval += s_c_retval) {
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _astrom = ((eraASTROM (*))astrom);
+- _eo = ((double (*))eo);
+- _c_retval = eraApco13(*_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _astrom, _eo);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_apcs(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *ebpv = *args++;
+- npy_intp s_ebpv = *steps++;
+- char *ehp = *args++;
+- npy_intp s_ehp = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_pv)[2][3];
+- double (*_ebpv)[2][3];
+- double b_ehp[3];
+- double (*_ehp)[3] = &b_ehp;
+- eraASTROM (*_astrom);
+- npy_intp is_ehp0 = *steps++;
+- int copy_ehp = (is_ehp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, pv += s_pv, ebpv += s_ebpv, ehp += s_ehp, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _pv = ((double (*)[2][3])pv);
+- _ebpv = ((double (*)[2][3])ebpv);
+- if (copy_ehp) {
+- copy_to_double3(ehp, is_ehp0, *_ehp);
+- }
+- else {
+- _ehp = ((double (*)[3])ehp);
+- }
+- _astrom = ((eraASTROM (*))astrom);
+- eraApcs(*_date1, *_date2, *_pv, *_ebpv, *_ehp, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apcs13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_pv)[2][3];
+- eraASTROM (*_astrom);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, pv += s_pv, astrom += s_astrom) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _pv = ((double (*)[2][3])pv);
+- _astrom = ((eraASTROM (*))astrom);
+- eraApcs13(*_date1, *_date2, *_pv, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_aper(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *astrom_in = *args++;
+- npy_intp s_astrom_in = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_theta);
+- eraASTROM (*_astrom);
+- for (i_o = 0; i_o < n_o;
+- i_o++, theta += s_theta, astrom += s_astrom, astrom_in += s_astrom_in) {
+- _theta = ((double (*))theta);
+- _astrom = ((eraASTROM (*))astrom);
+- if (astrom_in != astrom) {
+- memcpy(astrom, astrom_in, 1*sizeof(eraASTROM));
+- }
+- eraAper(*_theta, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_aper13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *astrom_in = *args++;
+- npy_intp s_astrom_in = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_ut11);
+- double (*_ut12);
+- eraASTROM (*_astrom);
+- for (i_o = 0; i_o < n_o;
+- i_o++, ut11 += s_ut11, ut12 += s_ut12, astrom += s_astrom, astrom_in += s_astrom_in) {
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _astrom = ((eraASTROM (*))astrom);
+- if (astrom_in != astrom) {
+- memcpy(astrom, astrom_in, 1*sizeof(eraASTROM));
+- }
+- eraAper13(*_ut11, *_ut12, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apio(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *sp = *args++;
+- npy_intp s_sp = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *refa = *args++;
+- npy_intp s_refa = *steps++;
+- char *refb = *args++;
+- npy_intp s_refb = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- double (*_sp);
+- double (*_theta);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_refa);
+- double (*_refb);
+- eraASTROM (*_astrom);
+- for (i_o = 0; i_o < n_o;
+- i_o++, sp += s_sp, theta += s_theta, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, refa += s_refa, refb += s_refb, astrom += s_astrom) {
+- _sp = ((double (*))sp);
+- _theta = ((double (*))theta);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _refa = ((double (*))refa);
+- _refb = ((double (*))refb);
+- _astrom = ((eraASTROM (*))astrom);
+- eraApio(*_sp, *_theta, *_elong, *_phi, *_hm, *_xp, *_yp, *_refa, *_refb, _astrom);
+- }
+-}
+-
+-static void ufunc_loop_apio13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- eraASTROM (*_astrom);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, astrom += s_astrom, c_retval += s_c_retval) {
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _astrom = ((eraASTROM (*))astrom);
+- _c_retval = eraApio13(*_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _astrom);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_atci13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *pr = *args++;
+- npy_intp s_pr = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *eo = *args++;
+- npy_intp s_eo = *steps++;
+- double (*_rc);
+- double (*_dc);
+- double (*_pr);
+- double (*_pd);
+- double (*_px);
+- double (*_rv);
+- double (*_date1);
+- double (*_date2);
+- double (*_ri);
+- double (*_di);
+- double (*_eo);
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, pr += s_pr, pd += s_pd, px += s_px, rv += s_rv, date1 += s_date1, date2 += s_date2, ri += s_ri, di += s_di, eo += s_eo) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _pr = ((double (*))pr);
+- _pd = ((double (*))pd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _eo = ((double (*))eo);
+- eraAtci13(*_rc, *_dc, *_pr, *_pd, *_px, *_rv, *_date1, *_date2, _ri, _di, _eo);
+- }
+-}
+-
+-static void ufunc_loop_atciq(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *pr = *args++;
+- npy_intp s_pr = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- double (*_rc);
+- double (*_dc);
+- double (*_pr);
+- double (*_pd);
+- double (*_px);
+- double (*_rv);
+- eraASTROM (*_astrom);
+- double (*_ri);
+- double (*_di);
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, pr += s_pr, pd += s_pd, px += s_px, rv += s_rv, astrom += s_astrom, ri += s_ri, di += s_di) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _pr = ((double (*))pr);
+- _pd = ((double (*))pd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _astrom = ((eraASTROM (*))astrom);
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- eraAtciq(*_rc, *_dc, *_pr, *_pd, *_px, *_rv, _astrom, _ri, _di);
+- }
+-}
+-
+-static void ufunc_loop_atciqn(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *pr = *args++;
+- npy_intp s_pr = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- double (*_rc);
+- double (*_dc);
+- double (*_pr);
+- double (*_pd);
+- double (*_px);
+- double (*_rv);
+- eraASTROM (*_astrom);
+- eraLDBODY (*_b);
+- double (*_ri);
+- double (*_di);
+- npy_intp nb = dimensions[0];
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(eraLDBODY));
+- if (copy_b) {
+- _b = PyArray_malloc(nb * sizeof(eraLDBODY));
+- if (_b == NULL) {
+- PyErr_NoMemory();
+- return;
+- }
+- }
+- else {
+- _b = NULL;
+- }
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, pr += s_pr, pd += s_pd, px += s_px, rv += s_rv, astrom += s_astrom, b += s_b, ri += s_ri, di += s_di) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _pr = ((double (*))pr);
+- _pd = ((double (*))pd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _astrom = ((eraASTROM (*))astrom);
+- if (copy_b) {
+- copy_to_eraLDBODY(b, is_b0, nb, _b);
+- }
+- else {
+- _b = ((eraLDBODY (*))b);
+- }
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- eraAtciqn(*_rc, *_dc, *_pr, *_pd, *_px, *_rv, _astrom, nb, _b, _ri, _di);
+- }
+-}
+-
+-static void ufunc_loop_atciqz(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- double (*_rc);
+- double (*_dc);
+- eraASTROM (*_astrom);
+- double (*_ri);
+- double (*_di);
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, astrom += s_astrom, ri += s_ri, di += s_di) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _astrom = ((eraASTROM (*))astrom);
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- eraAtciqz(*_rc, *_dc, _astrom, _ri, _di);
+- }
+-}
+-
+-static void ufunc_loop_atco13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *pr = *args++;
+- npy_intp s_pr = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *aob = *args++;
+- npy_intp s_aob = *steps++;
+- char *zob = *args++;
+- npy_intp s_zob = *steps++;
+- char *hob = *args++;
+- npy_intp s_hob = *steps++;
+- char *dob = *args++;
+- npy_intp s_dob = *steps++;
+- char *rob = *args++;
+- npy_intp s_rob = *steps++;
+- char *eo = *args++;
+- npy_intp s_eo = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_rc);
+- double (*_dc);
+- double (*_pr);
+- double (*_pd);
+- double (*_px);
+- double (*_rv);
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- double (*_aob);
+- double (*_zob);
+- double (*_hob);
+- double (*_dob);
+- double (*_rob);
+- double (*_eo);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, pr += s_pr, pd += s_pd, px += s_px, rv += s_rv, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, aob += s_aob, zob += s_zob, hob += s_hob, dob += s_dob, rob += s_rob, eo += s_eo, c_retval += s_c_retval) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _pr = ((double (*))pr);
+- _pd = ((double (*))pd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _aob = ((double (*))aob);
+- _zob = ((double (*))zob);
+- _hob = ((double (*))hob);
+- _dob = ((double (*))dob);
+- _rob = ((double (*))rob);
+- _eo = ((double (*))eo);
+- _c_retval = eraAtco13(*_rc, *_dc, *_pr, *_pd, *_px, *_rv, *_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _aob, _zob, _hob, _dob, _rob, _eo);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_atic13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *eo = *args++;
+- npy_intp s_eo = *steps++;
+- double (*_ri);
+- double (*_di);
+- double (*_date1);
+- double (*_date2);
+- double (*_rc);
+- double (*_dc);
+- double (*_eo);
+- for (i_o = 0; i_o < n_o;
+- i_o++, ri += s_ri, di += s_di, date1 += s_date1, date2 += s_date2, rc += s_rc, dc += s_dc, eo += s_eo) {
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _eo = ((double (*))eo);
+- eraAtic13(*_ri, *_di, *_date1, *_date2, _rc, _dc, _eo);
+- }
+-}
+-
+-static void ufunc_loop_aticq(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- double (*_ri);
+- double (*_di);
+- eraASTROM (*_astrom);
+- double (*_rc);
+- double (*_dc);
+- for (i_o = 0; i_o < n_o;
+- i_o++, ri += s_ri, di += s_di, astrom += s_astrom, rc += s_rc, dc += s_dc) {
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _astrom = ((eraASTROM (*))astrom);
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- eraAticq(*_ri, *_di, _astrom, _rc, _dc);
+- }
+-}
+-
+-static void ufunc_loop_aticqn(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- double (*_ri);
+- double (*_di);
+- eraASTROM (*_astrom);
+- eraLDBODY (*_b);
+- double (*_rc);
+- double (*_dc);
+- npy_intp nb = dimensions[0];
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(eraLDBODY));
+- if (copy_b) {
+- _b = PyArray_malloc(nb * sizeof(eraLDBODY));
+- if (_b == NULL) {
+- PyErr_NoMemory();
+- return;
+- }
+- }
+- else {
+- _b = NULL;
+- }
+- for (i_o = 0; i_o < n_o;
+- i_o++, ri += s_ri, di += s_di, astrom += s_astrom, b += s_b, rc += s_rc, dc += s_dc) {
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _astrom = ((eraASTROM (*))astrom);
+- if (copy_b) {
+- copy_to_eraLDBODY(b, is_b0, nb, _b);
+- }
+- else {
+- _b = ((eraLDBODY (*))b);
+- }
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- eraAticqn(*_ri, *_di, _astrom, nb, _b, _rc, _dc);
+- }
+-}
+-
+-static void ufunc_loop_atio13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *aob = *args++;
+- npy_intp s_aob = *steps++;
+- char *zob = *args++;
+- npy_intp s_zob = *steps++;
+- char *hob = *args++;
+- npy_intp s_hob = *steps++;
+- char *dob = *args++;
+- npy_intp s_dob = *steps++;
+- char *rob = *args++;
+- npy_intp s_rob = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ri);
+- double (*_di);
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- double (*_aob);
+- double (*_zob);
+- double (*_hob);
+- double (*_dob);
+- double (*_rob);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ri += s_ri, di += s_di, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, aob += s_aob, zob += s_zob, hob += s_hob, dob += s_dob, rob += s_rob, c_retval += s_c_retval) {
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _aob = ((double (*))aob);
+- _zob = ((double (*))zob);
+- _hob = ((double (*))hob);
+- _dob = ((double (*))dob);
+- _rob = ((double (*))rob);
+- _c_retval = eraAtio13(*_ri, *_di, *_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _aob, _zob, _hob, _dob, _rob);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_atioq(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *aob = *args++;
+- npy_intp s_aob = *steps++;
+- char *zob = *args++;
+- npy_intp s_zob = *steps++;
+- char *hob = *args++;
+- npy_intp s_hob = *steps++;
+- char *dob = *args++;
+- npy_intp s_dob = *steps++;
+- char *rob = *args++;
+- npy_intp s_rob = *steps++;
+- double (*_ri);
+- double (*_di);
+- eraASTROM (*_astrom);
+- double (*_aob);
+- double (*_zob);
+- double (*_hob);
+- double (*_dob);
+- double (*_rob);
+- for (i_o = 0; i_o < n_o;
+- i_o++, ri += s_ri, di += s_di, astrom += s_astrom, aob += s_aob, zob += s_zob, hob += s_hob, dob += s_dob, rob += s_rob) {
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _astrom = ((eraASTROM (*))astrom);
+- _aob = ((double (*))aob);
+- _zob = ((double (*))zob);
+- _hob = ((double (*))hob);
+- _dob = ((double (*))dob);
+- _rob = ((double (*))rob);
+- eraAtioq(*_ri, *_di, _astrom, _aob, _zob, _hob, _dob, _rob);
+- }
+-}
+-
+-static void ufunc_loop_atoc13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *type = *args++;
+- npy_intp s_type = *steps++;
+- char *ob1 = *args++;
+- npy_intp s_ob1 = *steps++;
+- char *ob2 = *args++;
+- npy_intp s_ob2 = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- const char (*_type);
+- double (*_ob1);
+- double (*_ob2);
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- double (*_rc);
+- double (*_dc);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, type += s_type, ob1 += s_ob1, ob2 += s_ob2, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, rc += s_rc, dc += s_dc, c_retval += s_c_retval) {
+- _type = ((const char (*))type);
+- _ob1 = ((double (*))ob1);
+- _ob2 = ((double (*))ob2);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _c_retval = eraAtoc13(_type, *_ob1, *_ob2, *_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _rc, _dc);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_atoi13(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *type = *args++;
+- npy_intp s_type = *steps++;
+- char *ob1 = *args++;
+- npy_intp s_ob1 = *steps++;
+- char *ob2 = *args++;
+- npy_intp s_ob2 = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- const char (*_type);
+- double (*_ob1);
+- double (*_ob2);
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- double (*_ri);
+- double (*_di);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, type += s_type, ob1 += s_ob1, ob2 += s_ob2, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, ri += s_ri, di += s_di, c_retval += s_c_retval) {
+- _type = ((const char (*))type);
+- _ob1 = ((double (*))ob1);
+- _ob2 = ((double (*))ob2);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- _c_retval = eraAtoi13(_type, *_ob1, *_ob2, *_utc1, *_utc2, *_dut1, *_elong, *_phi, *_hm, *_xp, *_yp, *_phpa, *_tc, *_rh, *_wl, _ri, _di);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_atoiq(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *type = *args++;
+- npy_intp s_type = *steps++;
+- char *ob1 = *args++;
+- npy_intp s_ob1 = *steps++;
+- char *ob2 = *args++;
+- npy_intp s_ob2 = *steps++;
+- char *astrom = *args++;
+- npy_intp s_astrom = *steps++;
+- char *ri = *args++;
+- npy_intp s_ri = *steps++;
+- char *di = *args++;
+- npy_intp s_di = *steps++;
+- const char (*_type);
+- double (*_ob1);
+- double (*_ob2);
+- eraASTROM (*_astrom);
+- double (*_ri);
+- double (*_di);
+- for (i_o = 0; i_o < n_o;
+- i_o++, type += s_type, ob1 += s_ob1, ob2 += s_ob2, astrom += s_astrom, ri += s_ri, di += s_di) {
+- _type = ((const char (*))type);
+- _ob1 = ((double (*))ob1);
+- _ob2 = ((double (*))ob2);
+- _astrom = ((eraASTROM (*))astrom);
+- _ri = ((double (*))ri);
+- _di = ((double (*))di);
+- eraAtoiq(_type, *_ob1, *_ob2, _astrom, _ri, _di);
+- }
+-}
+-
+-static void ufunc_loop_ld(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *bm = *args++;
+- npy_intp s_bm = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *q = *args++;
+- npy_intp s_q = *steps++;
+- char *e = *args++;
+- npy_intp s_e = *steps++;
+- char *em = *args++;
+- npy_intp s_em = *steps++;
+- char *dlim = *args++;
+- npy_intp s_dlim = *steps++;
+- char *p1 = *args++;
+- npy_intp s_p1 = *steps++;
+- double (*_bm);
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_q[3];
+- double (*_q)[3] = &b_q;
+- double b_e[3];
+- double (*_e)[3] = &b_e;
+- double (*_em);
+- double (*_dlim);
+- double b_p1[3];
+- double (*_p1)[3] = &b_p1;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_q0 = *steps++;
+- int copy_q = (is_q0 != sizeof(double));
+- npy_intp is_e0 = *steps++;
+- int copy_e = (is_e0 != sizeof(double));
+- npy_intp is_p10 = *steps++;
+- int copy_p1 = (is_p10 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, bm += s_bm, p += s_p, q += s_q, e += s_e, em += s_em, dlim += s_dlim, p1 += s_p1) {
+- _bm = ((double (*))bm);
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (copy_q) {
+- copy_to_double3(q, is_q0, *_q);
+- }
+- else {
+- _q = ((double (*)[3])q);
+- }
+- if (copy_e) {
+- copy_to_double3(e, is_e0, *_e);
+- }
+- else {
+- _e = ((double (*)[3])e);
+- }
+- _em = ((double (*))em);
+- _dlim = ((double (*))dlim);
+- if (!copy_p1) {
+- _p1 = ((double (*)[3])p1);
+- }
+- eraLd(*_bm, *_p, *_q, *_e, *_em, *_dlim, *_p1);
+- if (copy_p1) {
+- copy_from_double3(p1, is_p10, *_p1);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ldn(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *ob = *args++;
+- npy_intp s_ob = *steps++;
+- char *sc = *args++;
+- npy_intp s_sc = *steps++;
+- char *sn = *args++;
+- npy_intp s_sn = *steps++;
+- eraLDBODY (*_b);
+- double b_ob[3];
+- double (*_ob)[3] = &b_ob;
+- double b_sc[3];
+- double (*_sc)[3] = &b_sc;
+- double b_sn[3];
+- double (*_sn)[3] = &b_sn;
+- npy_intp nb = dimensions[0];
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(eraLDBODY));
+- npy_intp is_ob0 = *steps++;
+- int copy_ob = (is_ob0 != sizeof(double));
+- npy_intp is_sc0 = *steps++;
+- int copy_sc = (is_sc0 != sizeof(double));
+- npy_intp is_sn0 = *steps++;
+- int copy_sn = (is_sn0 != sizeof(double));
+- if (copy_b) {
+- _b = PyArray_malloc(nb * sizeof(eraLDBODY));
+- if (_b == NULL) {
+- PyErr_NoMemory();
+- return;
+- }
+- }
+- else {
+- _b = NULL;
+- }
+- for (i_o = 0; i_o < n_o;
+- i_o++, b += s_b, ob += s_ob, sc += s_sc, sn += s_sn) {
+- if (copy_b) {
+- copy_to_eraLDBODY(b, is_b0, nb, _b);
+- }
+- else {
+- _b = ((eraLDBODY (*))b);
+- }
+- if (copy_ob) {
+- copy_to_double3(ob, is_ob0, *_ob);
+- }
+- else {
+- _ob = ((double (*)[3])ob);
+- }
+- if (copy_sc) {
+- copy_to_double3(sc, is_sc0, *_sc);
+- }
+- else {
+- _sc = ((double (*)[3])sc);
+- }
+- if (!copy_sn) {
+- _sn = ((double (*)[3])sn);
+- }
+- eraLdn(nb, _b, *_ob, *_sc, *_sn);
+- if (copy_sn) {
+- copy_from_double3(sn, is_sn0, *_sn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ldsun(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *e = *args++;
+- npy_intp s_e = *steps++;
+- char *em = *args++;
+- npy_intp s_em = *steps++;
+- char *p1 = *args++;
+- npy_intp s_p1 = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_e[3];
+- double (*_e)[3] = &b_e;
+- double (*_em);
+- double b_p1[3];
+- double (*_p1)[3] = &b_p1;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_e0 = *steps++;
+- int copy_e = (is_e0 != sizeof(double));
+- npy_intp is_p10 = *steps++;
+- int copy_p1 = (is_p10 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, e += s_e, em += s_em, p1 += s_p1) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (copy_e) {
+- copy_to_double3(e, is_e0, *_e);
+- }
+- else {
+- _e = ((double (*)[3])e);
+- }
+- _em = ((double (*))em);
+- if (!copy_p1) {
+- _p1 = ((double (*)[3])p1);
+- }
+- eraLdsun(*_p, *_e, *_em, *_p1);
+- if (copy_p1) {
+- copy_from_double3(p1, is_p10, *_p1);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pmpx(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc = *args++;
+- npy_intp s_rc = *steps++;
+- char *dc = *args++;
+- npy_intp s_dc = *steps++;
+- char *pr = *args++;
+- npy_intp s_pr = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *pmt = *args++;
+- npy_intp s_pmt = *steps++;
+- char *pob = *args++;
+- npy_intp s_pob = *steps++;
+- char *pco = *args++;
+- npy_intp s_pco = *steps++;
+- double (*_rc);
+- double (*_dc);
+- double (*_pr);
+- double (*_pd);
+- double (*_px);
+- double (*_rv);
+- double (*_pmt);
+- double b_pob[3];
+- double (*_pob)[3] = &b_pob;
+- double b_pco[3];
+- double (*_pco)[3] = &b_pco;
+- npy_intp is_pob0 = *steps++;
+- int copy_pob = (is_pob0 != sizeof(double));
+- npy_intp is_pco0 = *steps++;
+- int copy_pco = (is_pco0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc += s_rc, dc += s_dc, pr += s_pr, pd += s_pd, px += s_px, rv += s_rv, pmt += s_pmt, pob += s_pob, pco += s_pco) {
+- _rc = ((double (*))rc);
+- _dc = ((double (*))dc);
+- _pr = ((double (*))pr);
+- _pd = ((double (*))pd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _pmt = ((double (*))pmt);
+- if (copy_pob) {
+- copy_to_double3(pob, is_pob0, *_pob);
+- }
+- else {
+- _pob = ((double (*)[3])pob);
+- }
+- if (!copy_pco) {
+- _pco = ((double (*)[3])pco);
+- }
+- eraPmpx(*_rc, *_dc, *_pr, *_pd, *_px, *_rv, *_pmt, *_pob, *_pco);
+- if (copy_pco) {
+- copy_from_double3(pco, is_pco0, *_pco);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pmsafe(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ra1 = *args++;
+- npy_intp s_ra1 = *steps++;
+- char *dec1 = *args++;
+- npy_intp s_dec1 = *steps++;
+- char *pmr1 = *args++;
+- npy_intp s_pmr1 = *steps++;
+- char *pmd1 = *args++;
+- npy_intp s_pmd1 = *steps++;
+- char *px1 = *args++;
+- npy_intp s_px1 = *steps++;
+- char *rv1 = *args++;
+- npy_intp s_rv1 = *steps++;
+- char *ep1a = *args++;
+- npy_intp s_ep1a = *steps++;
+- char *ep1b = *args++;
+- npy_intp s_ep1b = *steps++;
+- char *ep2a = *args++;
+- npy_intp s_ep2a = *steps++;
+- char *ep2b = *args++;
+- npy_intp s_ep2b = *steps++;
+- char *ra2 = *args++;
+- npy_intp s_ra2 = *steps++;
+- char *dec2 = *args++;
+- npy_intp s_dec2 = *steps++;
+- char *pmr2 = *args++;
+- npy_intp s_pmr2 = *steps++;
+- char *pmd2 = *args++;
+- npy_intp s_pmd2 = *steps++;
+- char *px2 = *args++;
+- npy_intp s_px2 = *steps++;
+- char *rv2 = *args++;
+- npy_intp s_rv2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ra1);
+- double (*_dec1);
+- double (*_pmr1);
+- double (*_pmd1);
+- double (*_px1);
+- double (*_rv1);
+- double (*_ep1a);
+- double (*_ep1b);
+- double (*_ep2a);
+- double (*_ep2b);
+- double (*_ra2);
+- double (*_dec2);
+- double (*_pmr2);
+- double (*_pmd2);
+- double (*_px2);
+- double (*_rv2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ra1 += s_ra1, dec1 += s_dec1, pmr1 += s_pmr1, pmd1 += s_pmd1, px1 += s_px1, rv1 += s_rv1, ep1a += s_ep1a, ep1b += s_ep1b, ep2a += s_ep2a, ep2b += s_ep2b, ra2 += s_ra2, dec2 += s_dec2, pmr2 += s_pmr2, pmd2 += s_pmd2, px2 += s_px2, rv2 += s_rv2, c_retval += s_c_retval) {
+- _ra1 = ((double (*))ra1);
+- _dec1 = ((double (*))dec1);
+- _pmr1 = ((double (*))pmr1);
+- _pmd1 = ((double (*))pmd1);
+- _px1 = ((double (*))px1);
+- _rv1 = ((double (*))rv1);
+- _ep1a = ((double (*))ep1a);
+- _ep1b = ((double (*))ep1b);
+- _ep2a = ((double (*))ep2a);
+- _ep2b = ((double (*))ep2b);
+- _ra2 = ((double (*))ra2);
+- _dec2 = ((double (*))dec2);
+- _pmr2 = ((double (*))pmr2);
+- _pmd2 = ((double (*))pmd2);
+- _px2 = ((double (*))px2);
+- _rv2 = ((double (*))rv2);
+- _c_retval = eraPmsafe(*_ra1, *_dec1, *_pmr1, *_pmd1, *_px1, *_rv1, *_ep1a, *_ep1b, *_ep2a, *_ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_pvtob(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *hm = *args++;
+- npy_intp s_hm = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *sp = *args++;
+- npy_intp s_sp = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- double (*_elong);
+- double (*_phi);
+- double (*_hm);
+- double (*_xp);
+- double (*_yp);
+- double (*_sp);
+- double (*_theta);
+- double (*_pv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, elong += s_elong, phi += s_phi, hm += s_hm, xp += s_xp, yp += s_yp, sp += s_sp, theta += s_theta, pv += s_pv) {
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _hm = ((double (*))hm);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _sp = ((double (*))sp);
+- _theta = ((double (*))theta);
+- _pv = ((double (*)[2][3])pv);
+- eraPvtob(*_elong, *_phi, *_hm, *_xp, *_yp, *_sp, *_theta, *_pv);
+- }
+-}
+-
+-static void ufunc_loop_refco(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *phpa = *args++;
+- npy_intp s_phpa = *steps++;
+- char *tc = *args++;
+- npy_intp s_tc = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *wl = *args++;
+- npy_intp s_wl = *steps++;
+- char *refa = *args++;
+- npy_intp s_refa = *steps++;
+- char *refb = *args++;
+- npy_intp s_refb = *steps++;
+- double (*_phpa);
+- double (*_tc);
+- double (*_rh);
+- double (*_wl);
+- double (*_refa);
+- double (*_refb);
+- for (i_o = 0; i_o < n_o;
+- i_o++, phpa += s_phpa, tc += s_tc, rh += s_rh, wl += s_wl, refa += s_refa, refb += s_refb) {
+- _phpa = ((double (*))phpa);
+- _tc = ((double (*))tc);
+- _rh = ((double (*))rh);
+- _wl = ((double (*))wl);
+- _refa = ((double (*))refa);
+- _refb = ((double (*))refb);
+- eraRefco(*_phpa, *_tc, *_rh, *_wl, _refa, _refb);
+- }
+-}
+-
+-static void ufunc_loop_epv00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *pvh = *args++;
+- npy_intp s_pvh = *steps++;
+- char *pvb = *args++;
+- npy_intp s_pvb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_pvh)[2][3];
+- double (*_pvb)[2][3];
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, pvh += s_pvh, pvb += s_pvb, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _pvh = ((double (*)[2][3])pvh);
+- _pvb = ((double (*)[2][3])pvb);
+- _c_retval = eraEpv00(*_date1, *_date2, *_pvh, *_pvb);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_plan94(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *np = *args++;
+- npy_intp s_np = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- int (*_np);
+- double (*_pv)[2][3];
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, np += s_np, pv += s_pv, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _np = ((int (*))np);
+- _pv = ((double (*)[2][3])pv);
+- _c_retval = eraPlan94(*_date1, *_date2, *_np, *_pv);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fad03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFad03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fae03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFae03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_faf03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFaf03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_faju03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFaju03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fal03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFal03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_falp03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFalp03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fama03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFama03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fame03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFame03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fane03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFane03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_faom03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFaom03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fapa03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFapa03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fasa03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFasa03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_faur03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFaur03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fave03(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *t = *args++;
+- npy_intp s_t = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_t);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, t += s_t, c_retval += s_c_retval) {
+- _t = ((double (*))t);
+- _c_retval = eraFave03(*_t);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_bi00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dpsibi = *args++;
+- npy_intp s_dpsibi = *steps++;
+- char *depsbi = *args++;
+- npy_intp s_depsbi = *steps++;
+- char *dra = *args++;
+- npy_intp s_dra = *steps++;
+- double (*_dpsibi);
+- double (*_depsbi);
+- double (*_dra);
+- for (i_o = 0; i_o < n_o;
+- i_o++, dpsibi += s_dpsibi, depsbi += s_depsbi, dra += s_dra) {
+- _dpsibi = ((double (*))dpsibi);
+- _depsbi = ((double (*))depsbi);
+- _dra = ((double (*))dra);
+- eraBi00(_dpsibi, _depsbi, _dra);
+- }
+-}
+-
+-static void ufunc_loop_bp00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rb += s_rb, rp += s_rp, rbp += s_rbp) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- eraBp00(*_date1, *_date2, *_rb, *_rp, *_rbp);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_bp06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rb += s_rb, rp += s_rp, rbp += s_rbp) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- eraBp06(*_date1, *_date2, *_rb, *_rp, *_rbp);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_bpn2xy(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- double (*_x);
+- double (*_y);
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, rbpn += s_rbpn, x += s_x, y += s_y) {
+- if (copy_rbpn) {
+- copy_to_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- else {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- eraBpn2xy(*_rbpn, _x, _y);
+- }
+-}
+-
+-static void ufunc_loop_c2i00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rc2i += s_rc2i) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2i00a(*_date1, *_date2, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2i00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rc2i += s_rc2i) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2i00b(*_date1, *_date2, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2i06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rc2i += s_rc2i) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2i06a(*_date1, *_date2, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2ibpn(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rbpn += s_rbpn, rc2i += s_rc2i) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (copy_rbpn) {
+- copy_to_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- else {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2ibpn(*_date1, *_date2, *_rbpn, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2ixy(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, rc2i += s_rc2i) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2ixy(*_date1, *_date2, *_x, *_y, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2ixys(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, x += s_x, y += s_y, s += s_s, rc2i += s_rc2i) {
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- if (!copy_rc2i) {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- eraC2ixys(*_x, *_y, *_s, *_rc2i);
+- if (copy_rc2i) {
+- copy_from_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2t00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double (*_tta);
+- double (*_ttb);
+- double (*_uta);
+- double (*_utb);
+- double (*_xp);
+- double (*_yp);
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, tta += s_tta, ttb += s_ttb, uta += s_uta, utb += s_utb, xp += s_xp, yp += s_yp, rc2t += s_rc2t) {
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2t00a(*_tta, *_ttb, *_uta, *_utb, *_xp, *_yp, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2t00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double (*_tta);
+- double (*_ttb);
+- double (*_uta);
+- double (*_utb);
+- double (*_xp);
+- double (*_yp);
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, tta += s_tta, ttb += s_ttb, uta += s_uta, utb += s_utb, xp += s_xp, yp += s_yp, rc2t += s_rc2t) {
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2t00b(*_tta, *_ttb, *_uta, *_utb, *_xp, *_yp, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2t06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double (*_tta);
+- double (*_ttb);
+- double (*_uta);
+- double (*_utb);
+- double (*_xp);
+- double (*_yp);
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, tta += s_tta, ttb += s_ttb, uta += s_uta, utb += s_utb, xp += s_xp, yp += s_yp, rc2t += s_rc2t) {
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2t06a(*_tta, *_ttb, *_uta, *_utb, *_xp, *_yp, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2tcio(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rc2i = *args++;
+- npy_intp s_rc2i = *steps++;
+- char *era = *args++;
+- npy_intp s_era = *steps++;
+- char *rpom = *args++;
+- npy_intp s_rpom = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double b_rc2i[3][3];
+- double (*_rc2i)[3][3] = &b_rc2i;
+- double (*_era);
+- double b_rpom[3][3];
+- double (*_rpom)[3][3] = &b_rpom;
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2i0 = *steps++;
+- npy_intp is_rc2i1 = *steps++;
+- int copy_rc2i = (is_rc2i1 != sizeof(double) &&
+- is_rc2i0 != 3 * sizeof(double));
+- npy_intp is_rpom0 = *steps++;
+- npy_intp is_rpom1 = *steps++;
+- int copy_rpom = (is_rpom1 != sizeof(double) &&
+- is_rpom0 != 3 * sizeof(double));
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, rc2i += s_rc2i, era += s_era, rpom += s_rpom, rc2t += s_rc2t) {
+- if (copy_rc2i) {
+- copy_to_double33(rc2i, is_rc2i0, is_rc2i1, *_rc2i);
+- }
+- else {
+- _rc2i = ((double (*)[3][3])rc2i);
+- }
+- _era = ((double (*))era);
+- if (copy_rpom) {
+- copy_to_double33(rpom, is_rpom0, is_rpom1, *_rpom);
+- }
+- else {
+- _rpom = ((double (*)[3][3])rpom);
+- }
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2tcio(*_rc2i, *_era, *_rpom, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2teqx(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- char *gst = *args++;
+- npy_intp s_gst = *steps++;
+- char *rpom = *args++;
+- npy_intp s_rpom = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- double (*_gst);
+- double b_rpom[3][3];
+- double (*_rpom)[3][3] = &b_rpom;
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- npy_intp is_rpom0 = *steps++;
+- npy_intp is_rpom1 = *steps++;
+- int copy_rpom = (is_rpom1 != sizeof(double) &&
+- is_rpom0 != 3 * sizeof(double));
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, rbpn += s_rbpn, gst += s_gst, rpom += s_rpom, rc2t += s_rc2t) {
+- if (copy_rbpn) {
+- copy_to_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- else {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- _gst = ((double (*))gst);
+- if (copy_rpom) {
+- copy_to_double33(rpom, is_rpom0, is_rpom1, *_rpom);
+- }
+- else {
+- _rpom = ((double (*)[3][3])rpom);
+- }
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2teqx(*_rbpn, *_gst, *_rpom, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2tpe(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double (*_tta);
+- double (*_ttb);
+- double (*_uta);
+- double (*_utb);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_xp);
+- double (*_yp);
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, tta += s_tta, ttb += s_ttb, uta += s_uta, utb += s_utb, dpsi += s_dpsi, deps += s_deps, xp += s_xp, yp += s_yp, rc2t += s_rc2t) {
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2tpe(*_tta, *_ttb, *_uta, *_utb, *_dpsi, *_deps, *_xp, *_yp, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_c2txy(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *rc2t = *args++;
+- npy_intp s_rc2t = *steps++;
+- double (*_tta);
+- double (*_ttb);
+- double (*_uta);
+- double (*_utb);
+- double (*_x);
+- double (*_y);
+- double (*_xp);
+- double (*_yp);
+- double b_rc2t[3][3];
+- double (*_rc2t)[3][3] = &b_rc2t;
+- npy_intp is_rc2t0 = *steps++;
+- npy_intp is_rc2t1 = *steps++;
+- int copy_rc2t = (is_rc2t1 != sizeof(double) &&
+- is_rc2t0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, tta += s_tta, ttb += s_ttb, uta += s_uta, utb += s_utb, x += s_x, y += s_y, xp += s_xp, yp += s_yp, rc2t += s_rc2t) {
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- if (!copy_rc2t) {
+- _rc2t = ((double (*)[3][3])rc2t);
+- }
+- eraC2txy(*_tta, *_ttb, *_uta, *_utb, *_x, *_y, *_xp, *_yp, *_rc2t);
+- if (copy_rc2t) {
+- copy_from_double33(rc2t, is_rc2t0, is_rc2t1, *_rc2t);
+- }
+- }
+-}
+-
+-static void ufunc_loop_eo06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEo06a(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_eors(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rnpb = *args++;
+- npy_intp s_rnpb = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_rnpb[3][3];
+- double (*_rnpb)[3][3] = &b_rnpb;
+- double (*_s);
+- double _c_retval;
+- npy_intp is_rnpb0 = *steps++;
+- npy_intp is_rnpb1 = *steps++;
+- int copy_rnpb = (is_rnpb1 != sizeof(double) &&
+- is_rnpb0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, rnpb += s_rnpb, s += s_s, c_retval += s_c_retval) {
+- if (copy_rnpb) {
+- copy_to_double33(rnpb, is_rnpb0, is_rnpb1, *_rnpb);
+- }
+- else {
+- _rnpb = ((double (*)[3][3])rnpb);
+- }
+- _s = ((double (*))s);
+- _c_retval = eraEors(*_rnpb, *_s);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fw2m(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *gamb = *args++;
+- npy_intp s_gamb = *steps++;
+- char *phib = *args++;
+- npy_intp s_phib = *steps++;
+- char *psi = *args++;
+- npy_intp s_psi = *steps++;
+- char *eps = *args++;
+- npy_intp s_eps = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double (*_gamb);
+- double (*_phib);
+- double (*_psi);
+- double (*_eps);
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, gamb += s_gamb, phib += s_phib, psi += s_psi, eps += s_eps, r += s_r) {
+- _gamb = ((double (*))gamb);
+- _phib = ((double (*))phib);
+- _psi = ((double (*))psi);
+- _eps = ((double (*))eps);
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- eraFw2m(*_gamb, *_phib, *_psi, *_eps, *_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_fw2xy(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *gamb = *args++;
+- npy_intp s_gamb = *steps++;
+- char *phib = *args++;
+- npy_intp s_phib = *steps++;
+- char *psi = *args++;
+- npy_intp s_psi = *steps++;
+- char *eps = *args++;
+- npy_intp s_eps = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- double (*_gamb);
+- double (*_phib);
+- double (*_psi);
+- double (*_eps);
+- double (*_x);
+- double (*_y);
+- for (i_o = 0; i_o < n_o;
+- i_o++, gamb += s_gamb, phib += s_phib, psi += s_psi, eps += s_eps, x += s_x, y += s_y) {
+- _gamb = ((double (*))gamb);
+- _phib = ((double (*))phib);
+- _psi = ((double (*))psi);
+- _eps = ((double (*))eps);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- eraFw2xy(*_gamb, *_phib, *_psi, *_eps, _x, _y);
+- }
+-}
+-
+-static void ufunc_loop_ltp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- double (*_epj);
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, rp += s_rp) {
+- _epj = ((double (*))epj);
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- eraLtp(*_epj, *_rp);
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ltpb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *rpb = *args++;
+- npy_intp s_rpb = *steps++;
+- double (*_epj);
+- double b_rpb[3][3];
+- double (*_rpb)[3][3] = &b_rpb;
+- npy_intp is_rpb0 = *steps++;
+- npy_intp is_rpb1 = *steps++;
+- int copy_rpb = (is_rpb1 != sizeof(double) &&
+- is_rpb0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, rpb += s_rpb) {
+- _epj = ((double (*))epj);
+- if (!copy_rpb) {
+- _rpb = ((double (*)[3][3])rpb);
+- }
+- eraLtpb(*_epj, *_rpb);
+- if (copy_rpb) {
+- copy_from_double33(rpb, is_rpb0, is_rpb1, *_rpb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ltpecl(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *vec = *args++;
+- npy_intp s_vec = *steps++;
+- double (*_epj);
+- double b_vec[3];
+- double (*_vec)[3] = &b_vec;
+- npy_intp is_vec0 = *steps++;
+- int copy_vec = (is_vec0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, vec += s_vec) {
+- _epj = ((double (*))epj);
+- if (!copy_vec) {
+- _vec = ((double (*)[3])vec);
+- }
+- eraLtpecl(*_epj, *_vec);
+- if (copy_vec) {
+- copy_from_double3(vec, is_vec0, *_vec);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ltpequ(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *veq = *args++;
+- npy_intp s_veq = *steps++;
+- double (*_epj);
+- double b_veq[3];
+- double (*_veq)[3] = &b_veq;
+- npy_intp is_veq0 = *steps++;
+- int copy_veq = (is_veq0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, veq += s_veq) {
+- _epj = ((double (*))epj);
+- if (!copy_veq) {
+- _veq = ((double (*)[3])veq);
+- }
+- eraLtpequ(*_epj, *_veq);
+- if (copy_veq) {
+- copy_from_double3(veq, is_veq0, *_veq);
+- }
+- }
+-}
+-
+-static void ufunc_loop_num00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatn = *args++;
+- npy_intp s_rmatn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatn[3][3];
+- double (*_rmatn)[3][3] = &b_rmatn;
+- npy_intp is_rmatn0 = *steps++;
+- npy_intp is_rmatn1 = *steps++;
+- int copy_rmatn = (is_rmatn1 != sizeof(double) &&
+- is_rmatn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatn += s_rmatn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatn) {
+- _rmatn = ((double (*)[3][3])rmatn);
+- }
+- eraNum00a(*_date1, *_date2, *_rmatn);
+- if (copy_rmatn) {
+- copy_from_double33(rmatn, is_rmatn0, is_rmatn1, *_rmatn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_num00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatn = *args++;
+- npy_intp s_rmatn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatn[3][3];
+- double (*_rmatn)[3][3] = &b_rmatn;
+- npy_intp is_rmatn0 = *steps++;
+- npy_intp is_rmatn1 = *steps++;
+- int copy_rmatn = (is_rmatn1 != sizeof(double) &&
+- is_rmatn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatn += s_rmatn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatn) {
+- _rmatn = ((double (*)[3][3])rmatn);
+- }
+- eraNum00b(*_date1, *_date2, *_rmatn);
+- if (copy_rmatn) {
+- copy_from_double33(rmatn, is_rmatn0, is_rmatn1, *_rmatn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_num06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatn = *args++;
+- npy_intp s_rmatn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatn[3][3];
+- double (*_rmatn)[3][3] = &b_rmatn;
+- npy_intp is_rmatn0 = *steps++;
+- npy_intp is_rmatn1 = *steps++;
+- int copy_rmatn = (is_rmatn1 != sizeof(double) &&
+- is_rmatn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatn += s_rmatn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatn) {
+- _rmatn = ((double (*)[3][3])rmatn);
+- }
+- eraNum06a(*_date1, *_date2, *_rmatn);
+- if (copy_rmatn) {
+- copy_from_double33(rmatn, is_rmatn0, is_rmatn1, *_rmatn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_numat(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *rmatn = *args++;
+- npy_intp s_rmatn = *steps++;
+- double (*_epsa);
+- double (*_dpsi);
+- double (*_deps);
+- double b_rmatn[3][3];
+- double (*_rmatn)[3][3] = &b_rmatn;
+- npy_intp is_rmatn0 = *steps++;
+- npy_intp is_rmatn1 = *steps++;
+- int copy_rmatn = (is_rmatn1 != sizeof(double) &&
+- is_rmatn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epsa += s_epsa, dpsi += s_dpsi, deps += s_deps, rmatn += s_rmatn) {
+- _epsa = ((double (*))epsa);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- if (!copy_rmatn) {
+- _rmatn = ((double (*)[3][3])rmatn);
+- }
+- eraNumat(*_epsa, *_dpsi, *_deps, *_rmatn);
+- if (copy_rmatn) {
+- copy_from_double33(rmatn, is_rmatn0, is_rmatn1, *_rmatn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_nut00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- eraNut00a(*_date1, *_date2, _dpsi, _deps);
+- }
+-}
+-
+-static void ufunc_loop_nut00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- eraNut00b(*_date1, *_date2, _dpsi, _deps);
+- }
+-}
+-
+-static void ufunc_loop_nut06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- eraNut06a(*_date1, *_date2, _dpsi, _deps);
+- }
+-}
+-
+-static void ufunc_loop_nut80(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- eraNut80(*_date1, *_date2, _dpsi, _deps);
+- }
+-}
+-
+-static void ufunc_loop_nutm80(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatn = *args++;
+- npy_intp s_rmatn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatn[3][3];
+- double (*_rmatn)[3][3] = &b_rmatn;
+- npy_intp is_rmatn0 = *steps++;
+- npy_intp is_rmatn1 = *steps++;
+- int copy_rmatn = (is_rmatn1 != sizeof(double) &&
+- is_rmatn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatn += s_rmatn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatn) {
+- _rmatn = ((double (*)[3][3])rmatn);
+- }
+- eraNutm80(*_date1, *_date2, *_rmatn);
+- if (copy_rmatn) {
+- copy_from_double33(rmatn, is_rmatn0, is_rmatn1, *_rmatn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_obl06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraObl06(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_obl80(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraObl80(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_p06e(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *eps0 = *args++;
+- npy_intp s_eps0 = *steps++;
+- char *psia = *args++;
+- npy_intp s_psia = *steps++;
+- char *oma = *args++;
+- npy_intp s_oma = *steps++;
+- char *bpa = *args++;
+- npy_intp s_bpa = *steps++;
+- char *bqa = *args++;
+- npy_intp s_bqa = *steps++;
+- char *pia = *args++;
+- npy_intp s_pia = *steps++;
+- char *bpia = *args++;
+- npy_intp s_bpia = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *chia = *args++;
+- npy_intp s_chia = *steps++;
+- char *za = *args++;
+- npy_intp s_za = *steps++;
+- char *zetaa = *args++;
+- npy_intp s_zetaa = *steps++;
+- char *thetaa = *args++;
+- npy_intp s_thetaa = *steps++;
+- char *pa = *args++;
+- npy_intp s_pa = *steps++;
+- char *gam = *args++;
+- npy_intp s_gam = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *psi = *args++;
+- npy_intp s_psi = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_eps0);
+- double (*_psia);
+- double (*_oma);
+- double (*_bpa);
+- double (*_bqa);
+- double (*_pia);
+- double (*_bpia);
+- double (*_epsa);
+- double (*_chia);
+- double (*_za);
+- double (*_zetaa);
+- double (*_thetaa);
+- double (*_pa);
+- double (*_gam);
+- double (*_phi);
+- double (*_psi);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, eps0 += s_eps0, psia += s_psia, oma += s_oma, bpa += s_bpa, bqa += s_bqa, pia += s_pia, bpia += s_bpia, epsa += s_epsa, chia += s_chia, za += s_za, zetaa += s_zetaa, thetaa += s_thetaa, pa += s_pa, gam += s_gam, phi += s_phi, psi += s_psi) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _eps0 = ((double (*))eps0);
+- _psia = ((double (*))psia);
+- _oma = ((double (*))oma);
+- _bpa = ((double (*))bpa);
+- _bqa = ((double (*))bqa);
+- _pia = ((double (*))pia);
+- _bpia = ((double (*))bpia);
+- _epsa = ((double (*))epsa);
+- _chia = ((double (*))chia);
+- _za = ((double (*))za);
+- _zetaa = ((double (*))zetaa);
+- _thetaa = ((double (*))thetaa);
+- _pa = ((double (*))pa);
+- _gam = ((double (*))gam);
+- _phi = ((double (*))phi);
+- _psi = ((double (*))psi);
+- eraP06e(*_date1, *_date2, _eps0, _psia, _oma, _bpa, _bqa, _pia, _bpia, _epsa, _chia, _za, _zetaa, _thetaa, _pa, _gam, _phi, _psi);
+- }
+-}
+-
+-static void ufunc_loop_pb06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *bzeta = *args++;
+- npy_intp s_bzeta = *steps++;
+- char *bz = *args++;
+- npy_intp s_bz = *steps++;
+- char *btheta = *args++;
+- npy_intp s_btheta = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_bzeta);
+- double (*_bz);
+- double (*_btheta);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, bzeta += s_bzeta, bz += s_bz, btheta += s_btheta) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _bzeta = ((double (*))bzeta);
+- _bz = ((double (*))bz);
+- _btheta = ((double (*))btheta);
+- eraPb06(*_date1, *_date2, _bzeta, _bz, _btheta);
+- }
+-}
+-
+-static void ufunc_loop_pfw06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *gamb = *args++;
+- npy_intp s_gamb = *steps++;
+- char *phib = *args++;
+- npy_intp s_phib = *steps++;
+- char *psib = *args++;
+- npy_intp s_psib = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_gamb);
+- double (*_phib);
+- double (*_psib);
+- double (*_epsa);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, gamb += s_gamb, phib += s_phib, psib += s_psib, epsa += s_epsa) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _gamb = ((double (*))gamb);
+- _phib = ((double (*))phib);
+- _psib = ((double (*))psib);
+- _epsa = ((double (*))epsa);
+- eraPfw06(*_date1, *_date2, _gamb, _phib, _psib, _epsa);
+- }
+-}
+-
+-static void ufunc_loop_pmat00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rbp += s_rbp) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- eraPmat00(*_date1, *_date2, *_rbp);
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pmat06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rbp += s_rbp) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- eraPmat06(*_date1, *_date2, *_rbp);
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pmat76(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatp = *args++;
+- npy_intp s_rmatp = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatp[3][3];
+- double (*_rmatp)[3][3] = &b_rmatp;
+- npy_intp is_rmatp0 = *steps++;
+- npy_intp is_rmatp1 = *steps++;
+- int copy_rmatp = (is_rmatp1 != sizeof(double) &&
+- is_rmatp0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatp += s_rmatp) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatp) {
+- _rmatp = ((double (*)[3][3])rmatp);
+- }
+- eraPmat76(*_date1, *_date2, *_rmatp);
+- if (copy_rmatp) {
+- copy_from_double33(rmatp, is_rmatp0, is_rmatp1, *_rmatp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- char *rn = *args++;
+- npy_intp s_rn = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_epsa);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- double b_rn[3][3];
+- double (*_rn)[3][3] = &b_rn;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- npy_intp is_rn0 = *steps++;
+- npy_intp is_rn1 = *steps++;
+- int copy_rn = (is_rn1 != sizeof(double) &&
+- is_rn0 != 3 * sizeof(double));
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps, epsa += s_epsa, rb += s_rb, rp += s_rp, rbp += s_rbp, rn += s_rn, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _epsa = ((double (*))epsa);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- if (!copy_rn) {
+- _rn = ((double (*)[3][3])rn);
+- }
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPn00(*_date1, *_date2, *_dpsi, *_deps, _epsa, *_rb, *_rp, *_rbp, *_rn, *_rbpn);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- if (copy_rn) {
+- copy_from_double33(rn, is_rn0, is_rn1, *_rn);
+- }
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- char *rn = *args++;
+- npy_intp s_rn = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_epsa);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- double b_rn[3][3];
+- double (*_rn)[3][3] = &b_rn;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- npy_intp is_rn0 = *steps++;
+- npy_intp is_rn1 = *steps++;
+- int copy_rn = (is_rn1 != sizeof(double) &&
+- is_rn0 != 3 * sizeof(double));
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps, epsa += s_epsa, rb += s_rb, rp += s_rp, rbp += s_rbp, rn += s_rn, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _epsa = ((double (*))epsa);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- if (!copy_rn) {
+- _rn = ((double (*)[3][3])rn);
+- }
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPn00a(*_date1, *_date2, _dpsi, _deps, _epsa, *_rb, *_rp, *_rbp, *_rn, *_rbpn);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- if (copy_rn) {
+- copy_from_double33(rn, is_rn0, is_rn1, *_rn);
+- }
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- char *rn = *args++;
+- npy_intp s_rn = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_epsa);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- double b_rn[3][3];
+- double (*_rn)[3][3] = &b_rn;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- npy_intp is_rn0 = *steps++;
+- npy_intp is_rn1 = *steps++;
+- int copy_rn = (is_rn1 != sizeof(double) &&
+- is_rn0 != 3 * sizeof(double));
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps, epsa += s_epsa, rb += s_rb, rp += s_rp, rbp += s_rbp, rn += s_rn, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _epsa = ((double (*))epsa);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- if (!copy_rn) {
+- _rn = ((double (*)[3][3])rn);
+- }
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPn00b(*_date1, *_date2, _dpsi, _deps, _epsa, *_rb, *_rp, *_rbp, *_rn, *_rbpn);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- if (copy_rn) {
+- copy_from_double33(rn, is_rn0, is_rn1, *_rn);
+- }
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- char *rn = *args++;
+- npy_intp s_rn = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_epsa);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- double b_rn[3][3];
+- double (*_rn)[3][3] = &b_rn;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- npy_intp is_rn0 = *steps++;
+- npy_intp is_rn1 = *steps++;
+- int copy_rn = (is_rn1 != sizeof(double) &&
+- is_rn0 != 3 * sizeof(double));
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps, epsa += s_epsa, rb += s_rb, rp += s_rp, rbp += s_rbp, rn += s_rn, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _epsa = ((double (*))epsa);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- if (!copy_rn) {
+- _rn = ((double (*)[3][3])rn);
+- }
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPn06(*_date1, *_date2, *_dpsi, *_deps, _epsa, *_rb, *_rp, *_rbp, *_rn, *_rbpn);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- if (copy_rn) {
+- copy_from_double33(rn, is_rn0, is_rn1, *_rn);
+- }
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *deps = *args++;
+- npy_intp s_deps = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *rb = *args++;
+- npy_intp s_rb = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- char *rbp = *args++;
+- npy_intp s_rbp = *steps++;
+- char *rn = *args++;
+- npy_intp s_rn = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsi);
+- double (*_deps);
+- double (*_epsa);
+- double b_rb[3][3];
+- double (*_rb)[3][3] = &b_rb;
+- double b_rp[3][3];
+- double (*_rp)[3][3] = &b_rp;
+- double b_rbp[3][3];
+- double (*_rbp)[3][3] = &b_rbp;
+- double b_rn[3][3];
+- double (*_rn)[3][3] = &b_rn;
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rb0 = *steps++;
+- npy_intp is_rb1 = *steps++;
+- int copy_rb = (is_rb1 != sizeof(double) &&
+- is_rb0 != 3 * sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- npy_intp is_rp1 = *steps++;
+- int copy_rp = (is_rp1 != sizeof(double) &&
+- is_rp0 != 3 * sizeof(double));
+- npy_intp is_rbp0 = *steps++;
+- npy_intp is_rbp1 = *steps++;
+- int copy_rbp = (is_rbp1 != sizeof(double) &&
+- is_rbp0 != 3 * sizeof(double));
+- npy_intp is_rn0 = *steps++;
+- npy_intp is_rn1 = *steps++;
+- int copy_rn = (is_rn1 != sizeof(double) &&
+- is_rn0 != 3 * sizeof(double));
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsi += s_dpsi, deps += s_deps, epsa += s_epsa, rb += s_rb, rp += s_rp, rbp += s_rbp, rn += s_rn, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsi = ((double (*))dpsi);
+- _deps = ((double (*))deps);
+- _epsa = ((double (*))epsa);
+- if (!copy_rb) {
+- _rb = ((double (*)[3][3])rb);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3][3])rp);
+- }
+- if (!copy_rbp) {
+- _rbp = ((double (*)[3][3])rbp);
+- }
+- if (!copy_rn) {
+- _rn = ((double (*)[3][3])rn);
+- }
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPn06a(*_date1, *_date2, _dpsi, _deps, _epsa, *_rb, *_rp, *_rbp, *_rn, *_rbpn);
+- if (copy_rb) {
+- copy_from_double33(rb, is_rb0, is_rb1, *_rb);
+- }
+- if (copy_rp) {
+- copy_from_double33(rp, is_rp0, is_rp1, *_rp);
+- }
+- if (copy_rbp) {
+- copy_from_double33(rbp, is_rbp0, is_rbp1, *_rbp);
+- }
+- if (copy_rn) {
+- copy_from_double33(rn, is_rn0, is_rn1, *_rn);
+- }
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pnm00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPnm00a(*_date1, *_date2, *_rbpn);
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pnm00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rbpn = *args++;
+- npy_intp s_rbpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rbpn[3][3];
+- double (*_rbpn)[3][3] = &b_rbpn;
+- npy_intp is_rbpn0 = *steps++;
+- npy_intp is_rbpn1 = *steps++;
+- int copy_rbpn = (is_rbpn1 != sizeof(double) &&
+- is_rbpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rbpn += s_rbpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rbpn) {
+- _rbpn = ((double (*)[3][3])rbpn);
+- }
+- eraPnm00b(*_date1, *_date2, *_rbpn);
+- if (copy_rbpn) {
+- copy_from_double33(rbpn, is_rbpn0, is_rbpn1, *_rbpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pnm06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rnpb = *args++;
+- npy_intp s_rnpb = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rnpb[3][3];
+- double (*_rnpb)[3][3] = &b_rnpb;
+- npy_intp is_rnpb0 = *steps++;
+- npy_intp is_rnpb1 = *steps++;
+- int copy_rnpb = (is_rnpb1 != sizeof(double) &&
+- is_rnpb0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rnpb += s_rnpb) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rnpb) {
+- _rnpb = ((double (*)[3][3])rnpb);
+- }
+- eraPnm06a(*_date1, *_date2, *_rnpb);
+- if (copy_rnpb) {
+- copy_from_double33(rnpb, is_rnpb0, is_rnpb1, *_rnpb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pnm80(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rmatpn = *args++;
+- npy_intp s_rmatpn = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rmatpn[3][3];
+- double (*_rmatpn)[3][3] = &b_rmatpn;
+- npy_intp is_rmatpn0 = *steps++;
+- npy_intp is_rmatpn1 = *steps++;
+- int copy_rmatpn = (is_rmatpn1 != sizeof(double) &&
+- is_rmatpn0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rmatpn += s_rmatpn) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rmatpn) {
+- _rmatpn = ((double (*)[3][3])rmatpn);
+- }
+- eraPnm80(*_date1, *_date2, *_rmatpn);
+- if (copy_rmatpn) {
+- copy_from_double33(rmatpn, is_rmatpn0, is_rmatpn1, *_rmatpn);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pom00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *xp = *args++;
+- npy_intp s_xp = *steps++;
+- char *yp = *args++;
+- npy_intp s_yp = *steps++;
+- char *sp = *args++;
+- npy_intp s_sp = *steps++;
+- char *rpom = *args++;
+- npy_intp s_rpom = *steps++;
+- double (*_xp);
+- double (*_yp);
+- double (*_sp);
+- double b_rpom[3][3];
+- double (*_rpom)[3][3] = &b_rpom;
+- npy_intp is_rpom0 = *steps++;
+- npy_intp is_rpom1 = *steps++;
+- int copy_rpom = (is_rpom1 != sizeof(double) &&
+- is_rpom0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, xp += s_xp, yp += s_yp, sp += s_sp, rpom += s_rpom) {
+- _xp = ((double (*))xp);
+- _yp = ((double (*))yp);
+- _sp = ((double (*))sp);
+- if (!copy_rpom) {
+- _rpom = ((double (*)[3][3])rpom);
+- }
+- eraPom00(*_xp, *_yp, *_sp, *_rpom);
+- if (copy_rpom) {
+- copy_from_double33(rpom, is_rpom0, is_rpom1, *_rpom);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pr00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dpsipr = *args++;
+- npy_intp s_dpsipr = *steps++;
+- char *depspr = *args++;
+- npy_intp s_depspr = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dpsipr);
+- double (*_depspr);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dpsipr += s_dpsipr, depspr += s_depspr) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dpsipr = ((double (*))dpsipr);
+- _depspr = ((double (*))depspr);
+- eraPr00(*_date1, *_date2, _dpsipr, _depspr);
+- }
+-}
+-
+-static void ufunc_loop_prec76(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date01 = *args++;
+- npy_intp s_date01 = *steps++;
+- char *date02 = *args++;
+- npy_intp s_date02 = *steps++;
+- char *date11 = *args++;
+- npy_intp s_date11 = *steps++;
+- char *date12 = *args++;
+- npy_intp s_date12 = *steps++;
+- char *zeta = *args++;
+- npy_intp s_zeta = *steps++;
+- char *z = *args++;
+- npy_intp s_z = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- double (*_date01);
+- double (*_date02);
+- double (*_date11);
+- double (*_date12);
+- double (*_zeta);
+- double (*_z);
+- double (*_theta);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date01 += s_date01, date02 += s_date02, date11 += s_date11, date12 += s_date12, zeta += s_zeta, z += s_z, theta += s_theta) {
+- _date01 = ((double (*))date01);
+- _date02 = ((double (*))date02);
+- _date11 = ((double (*))date11);
+- _date12 = ((double (*))date12);
+- _zeta = ((double (*))zeta);
+- _z = ((double (*))z);
+- _theta = ((double (*))theta);
+- eraPrec76(*_date01, *_date02, *_date11, *_date12, _zeta, _z, _theta);
+- }
+-}
+-
+-static void ufunc_loop_s00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _c_retval = eraS00(*_date1, *_date2, *_x, *_y);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_s00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraS00a(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_s00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraS00b(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_s06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _c_retval = eraS06(*_date1, *_date2, *_x, *_y);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_s06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraS06a(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_sp00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraSp00(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_xy06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- eraXy06(*_date1, *_date2, _x, _y);
+- }
+-}
+-
+-static void ufunc_loop_xys00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, s += s_s) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- eraXys00a(*_date1, *_date2, _x, _y, _s);
+- }
+-}
+-
+-static void ufunc_loop_xys00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, s += s_s) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- eraXys00b(*_date1, *_date2, _x, _y, _s);
+- }
+-}
+-
+-static void ufunc_loop_xys06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *x = *args++;
+- npy_intp s_x = *steps++;
+- char *y = *args++;
+- npy_intp s_y = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_x);
+- double (*_y);
+- double (*_s);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, x += s_x, y += s_y, s += s_s) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _x = ((double (*))x);
+- _y = ((double (*))y);
+- _s = ((double (*))s);
+- eraXys06a(*_date1, *_date2, _x, _y, _s);
+- }
+-}
+-
+-static void ufunc_loop_ee00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *epsa = *args++;
+- npy_intp s_epsa = *steps++;
+- char *dpsi = *args++;
+- npy_intp s_dpsi = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_epsa);
+- double (*_dpsi);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, epsa += s_epsa, dpsi += s_dpsi, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _epsa = ((double (*))epsa);
+- _dpsi = ((double (*))dpsi);
+- _c_retval = eraEe00(*_date1, *_date2, *_epsa, *_dpsi);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ee00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEe00a(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ee00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEe00b(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ee06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEe06a(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_eect00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEect00(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_eqeq94(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _c_retval = eraEqeq94(*_date1, *_date2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_era00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_dj1);
+- double (*_dj2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, dj1 += s_dj1, dj2 += s_dj2, c_retval += s_c_retval) {
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _c_retval = eraEra00(*_dj1, *_dj2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gmst00(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double (*_tta);
+- double (*_ttb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, tta += s_tta, ttb += s_ttb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _c_retval = eraGmst00(*_uta, *_utb, *_tta, *_ttb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gmst06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double (*_tta);
+- double (*_ttb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, tta += s_tta, ttb += s_ttb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _c_retval = eraGmst06(*_uta, *_utb, *_tta, *_ttb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gmst82(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dj1 = *args++;
+- npy_intp s_dj1 = *steps++;
+- char *dj2 = *args++;
+- npy_intp s_dj2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_dj1);
+- double (*_dj2);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, dj1 += s_dj1, dj2 += s_dj2, c_retval += s_c_retval) {
+- _dj1 = ((double (*))dj1);
+- _dj2 = ((double (*))dj2);
+- _c_retval = eraGmst82(*_dj1, *_dj2);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gst00a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double (*_tta);
+- double (*_ttb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, tta += s_tta, ttb += s_ttb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _c_retval = eraGst00a(*_uta, *_utb, *_tta, *_ttb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gst00b(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _c_retval = eraGst00b(*_uta, *_utb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gst06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *rnpb = *args++;
+- npy_intp s_rnpb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double (*_tta);
+- double (*_ttb);
+- double b_rnpb[3][3];
+- double (*_rnpb)[3][3] = &b_rnpb;
+- double _c_retval;
+- npy_intp is_rnpb0 = *steps++;
+- npy_intp is_rnpb1 = *steps++;
+- int copy_rnpb = (is_rnpb1 != sizeof(double) &&
+- is_rnpb0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, tta += s_tta, ttb += s_ttb, rnpb += s_rnpb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- if (copy_rnpb) {
+- copy_to_double33(rnpb, is_rnpb0, is_rnpb1, *_rnpb);
+- }
+- else {
+- _rnpb = ((double (*)[3][3])rnpb);
+- }
+- _c_retval = eraGst06(*_uta, *_utb, *_tta, *_ttb, *_rnpb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gst06a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *tta = *args++;
+- npy_intp s_tta = *steps++;
+- char *ttb = *args++;
+- npy_intp s_ttb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double (*_tta);
+- double (*_ttb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, tta += s_tta, ttb += s_ttb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _tta = ((double (*))tta);
+- _ttb = ((double (*))ttb);
+- _c_retval = eraGst06a(*_uta, *_utb, *_tta, *_ttb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gst94(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *uta = *args++;
+- npy_intp s_uta = *steps++;
+- char *utb = *args++;
+- npy_intp s_utb = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_uta);
+- double (*_utb);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, uta += s_uta, utb += s_utb, c_retval += s_c_retval) {
+- _uta = ((double (*))uta);
+- _utb = ((double (*))utb);
+- _c_retval = eraGst94(*_uta, *_utb);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_pvstar(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *ra = *args++;
+- npy_intp s_ra = *steps++;
+- char *dec = *args++;
+- npy_intp s_dec = *steps++;
+- char *pmr = *args++;
+- npy_intp s_pmr = *steps++;
+- char *pmd = *args++;
+- npy_intp s_pmd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_pv)[2][3];
+- double (*_ra);
+- double (*_dec);
+- double (*_pmr);
+- double (*_pmd);
+- double (*_px);
+- double (*_rv);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, ra += s_ra, dec += s_dec, pmr += s_pmr, pmd += s_pmd, px += s_px, rv += s_rv, c_retval += s_c_retval) {
+- _pv = ((double (*)[2][3])pv);
+- _ra = ((double (*))ra);
+- _dec = ((double (*))dec);
+- _pmr = ((double (*))pmr);
+- _pmd = ((double (*))pmd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _c_retval = eraPvstar(*_pv, _ra, _dec, _pmr, _pmd, _px, _rv);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_starpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ra = *args++;
+- npy_intp s_ra = *steps++;
+- char *dec = *args++;
+- npy_intp s_dec = *steps++;
+- char *pmr = *args++;
+- npy_intp s_pmr = *steps++;
+- char *pmd = *args++;
+- npy_intp s_pmd = *steps++;
+- char *px = *args++;
+- npy_intp s_px = *steps++;
+- char *rv = *args++;
+- npy_intp s_rv = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ra);
+- double (*_dec);
+- double (*_pmr);
+- double (*_pmd);
+- double (*_px);
+- double (*_rv);
+- double (*_pv)[2][3];
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ra += s_ra, dec += s_dec, pmr += s_pmr, pmd += s_pmd, px += s_px, rv += s_rv, pv += s_pv, c_retval += s_c_retval) {
+- _ra = ((double (*))ra);
+- _dec = ((double (*))dec);
+- _pmr = ((double (*))pmr);
+- _pmd = ((double (*))pmd);
+- _px = ((double (*))px);
+- _rv = ((double (*))rv);
+- _pv = ((double (*)[2][3])pv);
+- _c_retval = eraStarpv(*_ra, *_dec, *_pmr, *_pmd, *_px, *_rv, *_pv);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_fk425(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r1950 = *args++;
+- npy_intp s_r1950 = *steps++;
+- char *d1950 = *args++;
+- npy_intp s_d1950 = *steps++;
+- char *dr1950 = *args++;
+- npy_intp s_dr1950 = *steps++;
+- char *dd1950 = *args++;
+- npy_intp s_dd1950 = *steps++;
+- char *p1950 = *args++;
+- npy_intp s_p1950 = *steps++;
+- char *v1950 = *args++;
+- npy_intp s_v1950 = *steps++;
+- char *r2000 = *args++;
+- npy_intp s_r2000 = *steps++;
+- char *d2000 = *args++;
+- npy_intp s_d2000 = *steps++;
+- char *dr2000 = *args++;
+- npy_intp s_dr2000 = *steps++;
+- char *dd2000 = *args++;
+- npy_intp s_dd2000 = *steps++;
+- char *p2000 = *args++;
+- npy_intp s_p2000 = *steps++;
+- char *v2000 = *args++;
+- npy_intp s_v2000 = *steps++;
+- double (*_r1950);
+- double (*_d1950);
+- double (*_dr1950);
+- double (*_dd1950);
+- double (*_p1950);
+- double (*_v1950);
+- double (*_r2000);
+- double (*_d2000);
+- double (*_dr2000);
+- double (*_dd2000);
+- double (*_p2000);
+- double (*_v2000);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r1950 += s_r1950, d1950 += s_d1950, dr1950 += s_dr1950, dd1950 += s_dd1950, p1950 += s_p1950, v1950 += s_v1950, r2000 += s_r2000, d2000 += s_d2000, dr2000 += s_dr2000, dd2000 += s_dd2000, p2000 += s_p2000, v2000 += s_v2000) {
+- _r1950 = ((double (*))r1950);
+- _d1950 = ((double (*))d1950);
+- _dr1950 = ((double (*))dr1950);
+- _dd1950 = ((double (*))dd1950);
+- _p1950 = ((double (*))p1950);
+- _v1950 = ((double (*))v1950);
+- _r2000 = ((double (*))r2000);
+- _d2000 = ((double (*))d2000);
+- _dr2000 = ((double (*))dr2000);
+- _dd2000 = ((double (*))dd2000);
+- _p2000 = ((double (*))p2000);
+- _v2000 = ((double (*))v2000);
+- eraFk425(*_r1950, *_d1950, *_dr1950, *_dd1950, *_p1950, *_v1950, _r2000, _d2000, _dr2000, _dd2000, _p2000, _v2000);
+- }
+-}
+-
+-static void ufunc_loop_fk45z(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r1950 = *args++;
+- npy_intp s_r1950 = *steps++;
+- char *d1950 = *args++;
+- npy_intp s_d1950 = *steps++;
+- char *bepoch = *args++;
+- npy_intp s_bepoch = *steps++;
+- char *r2000 = *args++;
+- npy_intp s_r2000 = *steps++;
+- char *d2000 = *args++;
+- npy_intp s_d2000 = *steps++;
+- double (*_r1950);
+- double (*_d1950);
+- double (*_bepoch);
+- double (*_r2000);
+- double (*_d2000);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r1950 += s_r1950, d1950 += s_d1950, bepoch += s_bepoch, r2000 += s_r2000, d2000 += s_d2000) {
+- _r1950 = ((double (*))r1950);
+- _d1950 = ((double (*))d1950);
+- _bepoch = ((double (*))bepoch);
+- _r2000 = ((double (*))r2000);
+- _d2000 = ((double (*))d2000);
+- eraFk45z(*_r1950, *_d1950, *_bepoch, _r2000, _d2000);
+- }
+-}
+-
+-static void ufunc_loop_fk524(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r2000 = *args++;
+- npy_intp s_r2000 = *steps++;
+- char *d2000 = *args++;
+- npy_intp s_d2000 = *steps++;
+- char *dr2000 = *args++;
+- npy_intp s_dr2000 = *steps++;
+- char *dd2000 = *args++;
+- npy_intp s_dd2000 = *steps++;
+- char *p2000 = *args++;
+- npy_intp s_p2000 = *steps++;
+- char *v2000 = *args++;
+- npy_intp s_v2000 = *steps++;
+- char *r1950 = *args++;
+- npy_intp s_r1950 = *steps++;
+- char *d1950 = *args++;
+- npy_intp s_d1950 = *steps++;
+- char *dr1950 = *args++;
+- npy_intp s_dr1950 = *steps++;
+- char *dd1950 = *args++;
+- npy_intp s_dd1950 = *steps++;
+- char *p1950 = *args++;
+- npy_intp s_p1950 = *steps++;
+- char *v1950 = *args++;
+- npy_intp s_v1950 = *steps++;
+- double (*_r2000);
+- double (*_d2000);
+- double (*_dr2000);
+- double (*_dd2000);
+- double (*_p2000);
+- double (*_v2000);
+- double (*_r1950);
+- double (*_d1950);
+- double (*_dr1950);
+- double (*_dd1950);
+- double (*_p1950);
+- double (*_v1950);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r2000 += s_r2000, d2000 += s_d2000, dr2000 += s_dr2000, dd2000 += s_dd2000, p2000 += s_p2000, v2000 += s_v2000, r1950 += s_r1950, d1950 += s_d1950, dr1950 += s_dr1950, dd1950 += s_dd1950, p1950 += s_p1950, v1950 += s_v1950) {
+- _r2000 = ((double (*))r2000);
+- _d2000 = ((double (*))d2000);
+- _dr2000 = ((double (*))dr2000);
+- _dd2000 = ((double (*))dd2000);
+- _p2000 = ((double (*))p2000);
+- _v2000 = ((double (*))v2000);
+- _r1950 = ((double (*))r1950);
+- _d1950 = ((double (*))d1950);
+- _dr1950 = ((double (*))dr1950);
+- _dd1950 = ((double (*))dd1950);
+- _p1950 = ((double (*))p1950);
+- _v1950 = ((double (*))v1950);
+- eraFk524(*_r2000, *_d2000, *_dr2000, *_dd2000, *_p2000, *_v2000, _r1950, _d1950, _dr1950, _dd1950, _p1950, _v1950);
+- }
+-}
+-
+-static void ufunc_loop_fk52h(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r5 = *args++;
+- npy_intp s_r5 = *steps++;
+- char *d5 = *args++;
+- npy_intp s_d5 = *steps++;
+- char *dr5 = *args++;
+- npy_intp s_dr5 = *steps++;
+- char *dd5 = *args++;
+- npy_intp s_dd5 = *steps++;
+- char *px5 = *args++;
+- npy_intp s_px5 = *steps++;
+- char *rv5 = *args++;
+- npy_intp s_rv5 = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *dh = *args++;
+- npy_intp s_dh = *steps++;
+- char *drh = *args++;
+- npy_intp s_drh = *steps++;
+- char *ddh = *args++;
+- npy_intp s_ddh = *steps++;
+- char *pxh = *args++;
+- npy_intp s_pxh = *steps++;
+- char *rvh = *args++;
+- npy_intp s_rvh = *steps++;
+- double (*_r5);
+- double (*_d5);
+- double (*_dr5);
+- double (*_dd5);
+- double (*_px5);
+- double (*_rv5);
+- double (*_rh);
+- double (*_dh);
+- double (*_drh);
+- double (*_ddh);
+- double (*_pxh);
+- double (*_rvh);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r5 += s_r5, d5 += s_d5, dr5 += s_dr5, dd5 += s_dd5, px5 += s_px5, rv5 += s_rv5, rh += s_rh, dh += s_dh, drh += s_drh, ddh += s_ddh, pxh += s_pxh, rvh += s_rvh) {
+- _r5 = ((double (*))r5);
+- _d5 = ((double (*))d5);
+- _dr5 = ((double (*))dr5);
+- _dd5 = ((double (*))dd5);
+- _px5 = ((double (*))px5);
+- _rv5 = ((double (*))rv5);
+- _rh = ((double (*))rh);
+- _dh = ((double (*))dh);
+- _drh = ((double (*))drh);
+- _ddh = ((double (*))ddh);
+- _pxh = ((double (*))pxh);
+- _rvh = ((double (*))rvh);
+- eraFk52h(*_r5, *_d5, *_dr5, *_dd5, *_px5, *_rv5, _rh, _dh, _drh, _ddh, _pxh, _rvh);
+- }
+-}
+-
+-static void ufunc_loop_fk54z(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r2000 = *args++;
+- npy_intp s_r2000 = *steps++;
+- char *d2000 = *args++;
+- npy_intp s_d2000 = *steps++;
+- char *bepoch = *args++;
+- npy_intp s_bepoch = *steps++;
+- char *r1950 = *args++;
+- npy_intp s_r1950 = *steps++;
+- char *d1950 = *args++;
+- npy_intp s_d1950 = *steps++;
+- char *dr1950 = *args++;
+- npy_intp s_dr1950 = *steps++;
+- char *dd1950 = *args++;
+- npy_intp s_dd1950 = *steps++;
+- double (*_r2000);
+- double (*_d2000);
+- double (*_bepoch);
+- double (*_r1950);
+- double (*_d1950);
+- double (*_dr1950);
+- double (*_dd1950);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r2000 += s_r2000, d2000 += s_d2000, bepoch += s_bepoch, r1950 += s_r1950, d1950 += s_d1950, dr1950 += s_dr1950, dd1950 += s_dd1950) {
+- _r2000 = ((double (*))r2000);
+- _d2000 = ((double (*))d2000);
+- _bepoch = ((double (*))bepoch);
+- _r1950 = ((double (*))r1950);
+- _d1950 = ((double (*))d1950);
+- _dr1950 = ((double (*))dr1950);
+- _dd1950 = ((double (*))dd1950);
+- eraFk54z(*_r2000, *_d2000, *_bepoch, _r1950, _d1950, _dr1950, _dd1950);
+- }
+-}
+-
+-static void ufunc_loop_fk5hip(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r5h = *args++;
+- npy_intp s_r5h = *steps++;
+- char *s5h = *args++;
+- npy_intp s_s5h = *steps++;
+- double b_r5h[3][3];
+- double (*_r5h)[3][3] = &b_r5h;
+- double b_s5h[3];
+- double (*_s5h)[3] = &b_s5h;
+- npy_intp is_r5h0 = *steps++;
+- npy_intp is_r5h1 = *steps++;
+- int copy_r5h = (is_r5h1 != sizeof(double) &&
+- is_r5h0 != 3 * sizeof(double));
+- npy_intp is_s5h0 = *steps++;
+- int copy_s5h = (is_s5h0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r5h += s_r5h, s5h += s_s5h) {
+- if (!copy_r5h) {
+- _r5h = ((double (*)[3][3])r5h);
+- }
+- if (!copy_s5h) {
+- _s5h = ((double (*)[3])s5h);
+- }
+- eraFk5hip(*_r5h, *_s5h);
+- if (copy_r5h) {
+- copy_from_double33(r5h, is_r5h0, is_r5h1, *_r5h);
+- }
+- if (copy_s5h) {
+- copy_from_double3(s5h, is_s5h0, *_s5h);
+- }
+- }
+-}
+-
+-static void ufunc_loop_fk5hz(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r5 = *args++;
+- npy_intp s_r5 = *steps++;
+- char *d5 = *args++;
+- npy_intp s_d5 = *steps++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *dh = *args++;
+- npy_intp s_dh = *steps++;
+- double (*_r5);
+- double (*_d5);
+- double (*_date1);
+- double (*_date2);
+- double (*_rh);
+- double (*_dh);
+- for (i_o = 0; i_o < n_o;
+- i_o++, r5 += s_r5, d5 += s_d5, date1 += s_date1, date2 += s_date2, rh += s_rh, dh += s_dh) {
+- _r5 = ((double (*))r5);
+- _d5 = ((double (*))d5);
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _rh = ((double (*))rh);
+- _dh = ((double (*))dh);
+- eraFk5hz(*_r5, *_d5, *_date1, *_date2, _rh, _dh);
+- }
+-}
+-
+-static void ufunc_loop_h2fk5(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *dh = *args++;
+- npy_intp s_dh = *steps++;
+- char *drh = *args++;
+- npy_intp s_drh = *steps++;
+- char *ddh = *args++;
+- npy_intp s_ddh = *steps++;
+- char *pxh = *args++;
+- npy_intp s_pxh = *steps++;
+- char *rvh = *args++;
+- npy_intp s_rvh = *steps++;
+- char *r5 = *args++;
+- npy_intp s_r5 = *steps++;
+- char *d5 = *args++;
+- npy_intp s_d5 = *steps++;
+- char *dr5 = *args++;
+- npy_intp s_dr5 = *steps++;
+- char *dd5 = *args++;
+- npy_intp s_dd5 = *steps++;
+- char *px5 = *args++;
+- npy_intp s_px5 = *steps++;
+- char *rv5 = *args++;
+- npy_intp s_rv5 = *steps++;
+- double (*_rh);
+- double (*_dh);
+- double (*_drh);
+- double (*_ddh);
+- double (*_pxh);
+- double (*_rvh);
+- double (*_r5);
+- double (*_d5);
+- double (*_dr5);
+- double (*_dd5);
+- double (*_px5);
+- double (*_rv5);
+- for (i_o = 0; i_o < n_o;
+- i_o++, rh += s_rh, dh += s_dh, drh += s_drh, ddh += s_ddh, pxh += s_pxh, rvh += s_rvh, r5 += s_r5, d5 += s_d5, dr5 += s_dr5, dd5 += s_dd5, px5 += s_px5, rv5 += s_rv5) {
+- _rh = ((double (*))rh);
+- _dh = ((double (*))dh);
+- _drh = ((double (*))drh);
+- _ddh = ((double (*))ddh);
+- _pxh = ((double (*))pxh);
+- _rvh = ((double (*))rvh);
+- _r5 = ((double (*))r5);
+- _d5 = ((double (*))d5);
+- _dr5 = ((double (*))dr5);
+- _dd5 = ((double (*))dd5);
+- _px5 = ((double (*))px5);
+- _rv5 = ((double (*))rv5);
+- eraH2fk5(*_rh, *_dh, *_drh, *_ddh, *_pxh, *_rvh, _r5, _d5, _dr5, _dd5, _px5, _rv5);
+- }
+-}
+-
+-static void ufunc_loop_hfk5z(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *rh = *args++;
+- npy_intp s_rh = *steps++;
+- char *dh = *args++;
+- npy_intp s_dh = *steps++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *r5 = *args++;
+- npy_intp s_r5 = *steps++;
+- char *d5 = *args++;
+- npy_intp s_d5 = *steps++;
+- char *dr5 = *args++;
+- npy_intp s_dr5 = *steps++;
+- char *dd5 = *args++;
+- npy_intp s_dd5 = *steps++;
+- double (*_rh);
+- double (*_dh);
+- double (*_date1);
+- double (*_date2);
+- double (*_r5);
+- double (*_d5);
+- double (*_dr5);
+- double (*_dd5);
+- for (i_o = 0; i_o < n_o;
+- i_o++, rh += s_rh, dh += s_dh, date1 += s_date1, date2 += s_date2, r5 += s_r5, d5 += s_d5, dr5 += s_dr5, dd5 += s_dd5) {
+- _rh = ((double (*))rh);
+- _dh = ((double (*))dh);
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _r5 = ((double (*))r5);
+- _d5 = ((double (*))d5);
+- _dr5 = ((double (*))dr5);
+- _dd5 = ((double (*))dd5);
+- eraHfk5z(*_rh, *_dh, *_date1, *_date2, _r5, _d5, _dr5, _dd5);
+- }
+-}
+-
+-static void ufunc_loop_starpm(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ra1 = *args++;
+- npy_intp s_ra1 = *steps++;
+- char *dec1 = *args++;
+- npy_intp s_dec1 = *steps++;
+- char *pmr1 = *args++;
+- npy_intp s_pmr1 = *steps++;
+- char *pmd1 = *args++;
+- npy_intp s_pmd1 = *steps++;
+- char *px1 = *args++;
+- npy_intp s_px1 = *steps++;
+- char *rv1 = *args++;
+- npy_intp s_rv1 = *steps++;
+- char *ep1a = *args++;
+- npy_intp s_ep1a = *steps++;
+- char *ep1b = *args++;
+- npy_intp s_ep1b = *steps++;
+- char *ep2a = *args++;
+- npy_intp s_ep2a = *steps++;
+- char *ep2b = *args++;
+- npy_intp s_ep2b = *steps++;
+- char *ra2 = *args++;
+- npy_intp s_ra2 = *steps++;
+- char *dec2 = *args++;
+- npy_intp s_dec2 = *steps++;
+- char *pmr2 = *args++;
+- npy_intp s_pmr2 = *steps++;
+- char *pmd2 = *args++;
+- npy_intp s_pmd2 = *steps++;
+- char *px2 = *args++;
+- npy_intp s_px2 = *steps++;
+- char *rv2 = *args++;
+- npy_intp s_rv2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ra1);
+- double (*_dec1);
+- double (*_pmr1);
+- double (*_pmd1);
+- double (*_px1);
+- double (*_rv1);
+- double (*_ep1a);
+- double (*_ep1b);
+- double (*_ep2a);
+- double (*_ep2b);
+- double (*_ra2);
+- double (*_dec2);
+- double (*_pmr2);
+- double (*_pmd2);
+- double (*_px2);
+- double (*_rv2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ra1 += s_ra1, dec1 += s_dec1, pmr1 += s_pmr1, pmd1 += s_pmd1, px1 += s_px1, rv1 += s_rv1, ep1a += s_ep1a, ep1b += s_ep1b, ep2a += s_ep2a, ep2b += s_ep2b, ra2 += s_ra2, dec2 += s_dec2, pmr2 += s_pmr2, pmd2 += s_pmd2, px2 += s_px2, rv2 += s_rv2, c_retval += s_c_retval) {
+- _ra1 = ((double (*))ra1);
+- _dec1 = ((double (*))dec1);
+- _pmr1 = ((double (*))pmr1);
+- _pmd1 = ((double (*))pmd1);
+- _px1 = ((double (*))px1);
+- _rv1 = ((double (*))rv1);
+- _ep1a = ((double (*))ep1a);
+- _ep1b = ((double (*))ep1b);
+- _ep2a = ((double (*))ep2a);
+- _ep2b = ((double (*))ep2b);
+- _ra2 = ((double (*))ra2);
+- _dec2 = ((double (*))dec2);
+- _pmr2 = ((double (*))pmr2);
+- _pmd2 = ((double (*))pmd2);
+- _px2 = ((double (*))px2);
+- _rv2 = ((double (*))rv2);
+- _c_retval = eraStarpm(*_ra1, *_dec1, *_pmr1, *_pmd1, *_px1, *_rv1, *_ep1a, *_ep1b, *_ep2a, *_ep2b, _ra2, _dec2, _pmr2, _pmd2, _px2, _rv2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_eceq06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dl);
+- double (*_db);
+- double (*_dr);
+- double (*_dd);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dl += s_dl, db += s_db, dr += s_dr, dd += s_dd) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- eraEceq06(*_date1, *_date2, *_dl, *_db, _dr, _dd);
+- }
+-}
+-
+-static void ufunc_loop_ecm06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *rm = *args++;
+- npy_intp s_rm = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double b_rm[3][3];
+- double (*_rm)[3][3] = &b_rm;
+- npy_intp is_rm0 = *steps++;
+- npy_intp is_rm1 = *steps++;
+- int copy_rm = (is_rm1 != sizeof(double) &&
+- is_rm0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, rm += s_rm) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- if (!copy_rm) {
+- _rm = ((double (*)[3][3])rm);
+- }
+- eraEcm06(*_date1, *_date2, *_rm);
+- if (copy_rm) {
+- copy_from_double33(rm, is_rm0, is_rm1, *_rm);
+- }
+- }
+-}
+-
+-static void ufunc_loop_eqec06(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_dr);
+- double (*_dd);
+- double (*_dl);
+- double (*_db);
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, dr += s_dr, dd += s_dd, dl += s_dl, db += s_db) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- eraEqec06(*_date1, *_date2, *_dr, *_dd, _dl, _db);
+- }
+-}
+-
+-static void ufunc_loop_lteceq(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- double (*_epj);
+- double (*_dl);
+- double (*_db);
+- double (*_dr);
+- double (*_dd);
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, dl += s_dl, db += s_db, dr += s_dr, dd += s_dd) {
+- _epj = ((double (*))epj);
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- eraLteceq(*_epj, *_dl, *_db, _dr, _dd);
+- }
+-}
+-
+-static void ufunc_loop_ltecm(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *rm = *args++;
+- npy_intp s_rm = *steps++;
+- double (*_epj);
+- double b_rm[3][3];
+- double (*_rm)[3][3] = &b_rm;
+- npy_intp is_rm0 = *steps++;
+- npy_intp is_rm1 = *steps++;
+- int copy_rm = (is_rm1 != sizeof(double) &&
+- is_rm0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, rm += s_rm) {
+- _epj = ((double (*))epj);
+- if (!copy_rm) {
+- _rm = ((double (*)[3][3])rm);
+- }
+- eraLtecm(*_epj, *_rm);
+- if (copy_rm) {
+- copy_from_double33(rm, is_rm0, is_rm1, *_rm);
+- }
+- }
+-}
+-
+-static void ufunc_loop_lteqec(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *epj = *args++;
+- npy_intp s_epj = *steps++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- double (*_epj);
+- double (*_dr);
+- double (*_dd);
+- double (*_dl);
+- double (*_db);
+- for (i_o = 0; i_o < n_o;
+- i_o++, epj += s_epj, dr += s_dr, dd += s_dd, dl += s_dl, db += s_db) {
+- _epj = ((double (*))epj);
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- eraLteqec(*_epj, *_dr, *_dd, _dl, _db);
+- }
+-}
+-
+-static void ufunc_loop_g2icrs(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- double (*_dl);
+- double (*_db);
+- double (*_dr);
+- double (*_dd);
+- for (i_o = 0; i_o < n_o;
+- i_o++, dl += s_dl, db += s_db, dr += s_dr, dd += s_dd) {
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- eraG2icrs(*_dl, *_db, _dr, _dd);
+- }
+-}
+-
+-static void ufunc_loop_icrs2g(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dr = *args++;
+- npy_intp s_dr = *steps++;
+- char *dd = *args++;
+- npy_intp s_dd = *steps++;
+- char *dl = *args++;
+- npy_intp s_dl = *steps++;
+- char *db = *args++;
+- npy_intp s_db = *steps++;
+- double (*_dr);
+- double (*_dd);
+- double (*_dl);
+- double (*_db);
+- for (i_o = 0; i_o < n_o;
+- i_o++, dr += s_dr, dd += s_dd, dl += s_dl, db += s_db) {
+- _dr = ((double (*))dr);
+- _dd = ((double (*))dd);
+- _dl = ((double (*))dl);
+- _db = ((double (*))db);
+- eraIcrs2g(*_dr, *_dd, _dl, _db);
+- }
+-}
+-
+-static void ufunc_loop_eform(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *n = *args++;
+- npy_intp s_n = *steps++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *f = *args++;
+- npy_intp s_f = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_n);
+- double (*_a);
+- double (*_f);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, n += s_n, a += s_a, f += s_f, c_retval += s_c_retval) {
+- _n = ((int (*))n);
+- _a = ((double (*))a);
+- _f = ((double (*))f);
+- _c_retval = eraEform(*_n, _a, _f);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gc2gd(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *n = *args++;
+- npy_intp s_n = *steps++;
+- char *xyz = *args++;
+- npy_intp s_xyz = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *height = *args++;
+- npy_intp s_height = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_n);
+- double b_xyz[3];
+- double (*_xyz)[3] = &b_xyz;
+- double (*_elong);
+- double (*_phi);
+- double (*_height);
+- int _c_retval;
+- npy_intp is_xyz0 = *steps++;
+- int copy_xyz = (is_xyz0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, n += s_n, xyz += s_xyz, elong += s_elong, phi += s_phi, height += s_height, c_retval += s_c_retval) {
+- _n = ((int (*))n);
+- if (copy_xyz) {
+- copy_to_double3(xyz, is_xyz0, *_xyz);
+- }
+- else {
+- _xyz = ((double (*)[3])xyz);
+- }
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _height = ((double (*))height);
+- _c_retval = eraGc2gd(*_n, *_xyz, _elong, _phi, _height);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gc2gde(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *f = *args++;
+- npy_intp s_f = *steps++;
+- char *xyz = *args++;
+- npy_intp s_xyz = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *height = *args++;
+- npy_intp s_height = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_a);
+- double (*_f);
+- double b_xyz[3];
+- double (*_xyz)[3] = &b_xyz;
+- double (*_elong);
+- double (*_phi);
+- double (*_height);
+- int _c_retval;
+- npy_intp is_xyz0 = *steps++;
+- int copy_xyz = (is_xyz0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, f += s_f, xyz += s_xyz, elong += s_elong, phi += s_phi, height += s_height, c_retval += s_c_retval) {
+- _a = ((double (*))a);
+- _f = ((double (*))f);
+- if (copy_xyz) {
+- copy_to_double3(xyz, is_xyz0, *_xyz);
+- }
+- else {
+- _xyz = ((double (*)[3])xyz);
+- }
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _height = ((double (*))height);
+- _c_retval = eraGc2gde(*_a, *_f, *_xyz, _elong, _phi, _height);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_gd2gc(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *n = *args++;
+- npy_intp s_n = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *height = *args++;
+- npy_intp s_height = *steps++;
+- char *xyz = *args++;
+- npy_intp s_xyz = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_n);
+- double (*_elong);
+- double (*_phi);
+- double (*_height);
+- double b_xyz[3];
+- double (*_xyz)[3] = &b_xyz;
+- int _c_retval;
+- npy_intp is_xyz0 = *steps++;
+- int copy_xyz = (is_xyz0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, n += s_n, elong += s_elong, phi += s_phi, height += s_height, xyz += s_xyz, c_retval += s_c_retval) {
+- _n = ((int (*))n);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _height = ((double (*))height);
+- if (!copy_xyz) {
+- _xyz = ((double (*)[3])xyz);
+- }
+- _c_retval = eraGd2gc(*_n, *_elong, *_phi, *_height, *_xyz);
+- *((int *)c_retval) = _c_retval;
+- if (copy_xyz) {
+- copy_from_double3(xyz, is_xyz0, *_xyz);
+- }
+- }
+-}
+-
+-static void ufunc_loop_gd2gce(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *f = *args++;
+- npy_intp s_f = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *height = *args++;
+- npy_intp s_height = *steps++;
+- char *xyz = *args++;
+- npy_intp s_xyz = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_a);
+- double (*_f);
+- double (*_elong);
+- double (*_phi);
+- double (*_height);
+- double b_xyz[3];
+- double (*_xyz)[3] = &b_xyz;
+- int _c_retval;
+- npy_intp is_xyz0 = *steps++;
+- int copy_xyz = (is_xyz0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, f += s_f, elong += s_elong, phi += s_phi, height += s_height, xyz += s_xyz, c_retval += s_c_retval) {
+- _a = ((double (*))a);
+- _f = ((double (*))f);
+- _elong = ((double (*))elong);
+- _phi = ((double (*))phi);
+- _height = ((double (*))height);
+- if (!copy_xyz) {
+- _xyz = ((double (*)[3])xyz);
+- }
+- _c_retval = eraGd2gce(*_a, *_f, *_elong, *_phi, *_height, *_xyz);
+- *((int *)c_retval) = _c_retval;
+- if (copy_xyz) {
+- copy_from_double3(xyz, is_xyz0, *_xyz);
+- }
+- }
+-}
+-
+-static void ufunc_loop_d2dtf(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *scale = *args++;
+- npy_intp s_scale = *steps++;
+- char *ndp = *args++;
+- npy_intp s_ndp = *steps++;
+- char *d1 = *args++;
+- npy_intp s_d1 = *steps++;
+- char *d2 = *args++;
+- npy_intp s_d2 = *steps++;
+- char *iy = *args++;
+- npy_intp s_iy = *steps++;
+- char *im = *args++;
+- npy_intp s_im = *steps++;
+- char *id = *args++;
+- npy_intp s_id = *steps++;
+- char *ihmsf = *args++;
+- npy_intp s_ihmsf = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- const char (*_scale);
+- int (*_ndp);
+- double (*_d1);
+- double (*_d2);
+- int (*_iy);
+- int (*_im);
+- int (*_id);
+- int (*_ihmsf)[4];
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, scale += s_scale, ndp += s_ndp, d1 += s_d1, d2 += s_d2, iy += s_iy, im += s_im, id += s_id, ihmsf += s_ihmsf, c_retval += s_c_retval) {
+- _scale = ((const char (*))scale);
+- _ndp = ((int (*))ndp);
+- _d1 = ((double (*))d1);
+- _d2 = ((double (*))d2);
+- _iy = ((int (*))iy);
+- _im = ((int (*))im);
+- _id = ((int (*))id);
+- _ihmsf = ((int (*)[4])ihmsf);
+- _c_retval = eraD2dtf(_scale, *_ndp, *_d1, *_d2, _iy, _im, _id, *_ihmsf);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_dat(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *iy = *args++;
+- npy_intp s_iy = *steps++;
+- char *im = *args++;
+- npy_intp s_im = *steps++;
+- char *id = *args++;
+- npy_intp s_id = *steps++;
+- char *fd = *args++;
+- npy_intp s_fd = *steps++;
+- char *deltat = *args++;
+- npy_intp s_deltat = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- int (*_iy);
+- int (*_im);
+- int (*_id);
+- double (*_fd);
+- double (*_deltat);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, iy += s_iy, im += s_im, id += s_id, fd += s_fd, deltat += s_deltat, c_retval += s_c_retval) {
+- _iy = ((int (*))iy);
+- _im = ((int (*))im);
+- _id = ((int (*))id);
+- _fd = ((double (*))fd);
+- _deltat = ((double (*))deltat);
+- _c_retval = eraDat(*_iy, *_im, *_id, *_fd, _deltat);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_dtdb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *date1 = *args++;
+- npy_intp s_date1 = *steps++;
+- char *date2 = *args++;
+- npy_intp s_date2 = *steps++;
+- char *ut = *args++;
+- npy_intp s_ut = *steps++;
+- char *elong = *args++;
+- npy_intp s_elong = *steps++;
+- char *u = *args++;
+- npy_intp s_u = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_date1);
+- double (*_date2);
+- double (*_ut);
+- double (*_elong);
+- double (*_u);
+- double (*_v);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, date1 += s_date1, date2 += s_date2, ut += s_ut, elong += s_elong, u += s_u, v += s_v, c_retval += s_c_retval) {
+- _date1 = ((double (*))date1);
+- _date2 = ((double (*))date2);
+- _ut = ((double (*))ut);
+- _elong = ((double (*))elong);
+- _u = ((double (*))u);
+- _v = ((double (*))v);
+- _c_retval = eraDtdb(*_date1, *_date2, *_ut, *_elong, *_u, *_v);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_dtf2d(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *scale = *args++;
+- npy_intp s_scale = *steps++;
+- char *iy = *args++;
+- npy_intp s_iy = *steps++;
+- char *im = *args++;
+- npy_intp s_im = *steps++;
+- char *id = *args++;
+- npy_intp s_id = *steps++;
+- char *ihr = *args++;
+- npy_intp s_ihr = *steps++;
+- char *imn = *args++;
+- npy_intp s_imn = *steps++;
+- char *sec = *args++;
+- npy_intp s_sec = *steps++;
+- char *d1 = *args++;
+- npy_intp s_d1 = *steps++;
+- char *d2 = *args++;
+- npy_intp s_d2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- const char (*_scale);
+- int (*_iy);
+- int (*_im);
+- int (*_id);
+- int (*_ihr);
+- int (*_imn);
+- double (*_sec);
+- double (*_d1);
+- double (*_d2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, scale += s_scale, iy += s_iy, im += s_im, id += s_id, ihr += s_ihr, imn += s_imn, sec += s_sec, d1 += s_d1, d2 += s_d2, c_retval += s_c_retval) {
+- _scale = ((const char (*))scale);
+- _iy = ((int (*))iy);
+- _im = ((int (*))im);
+- _id = ((int (*))id);
+- _ihr = ((int (*))ihr);
+- _imn = ((int (*))imn);
+- _sec = ((double (*))sec);
+- _d1 = ((double (*))d1);
+- _d2 = ((double (*))d2);
+- _c_retval = eraDtf2d(_scale, *_iy, *_im, *_id, *_ihr, *_imn, *_sec, _d1, _d2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_taitt(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tai1);
+- double (*_tai2);
+- double (*_tt1);
+- double (*_tt2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tai1 += s_tai1, tai2 += s_tai2, tt1 += s_tt1, tt2 += s_tt2, c_retval += s_c_retval) {
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _c_retval = eraTaitt(*_tai1, *_tai2, _tt1, _tt2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_taiut1(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *dta = *args++;
+- npy_intp s_dta = *steps++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tai1);
+- double (*_tai2);
+- double (*_dta);
+- double (*_ut11);
+- double (*_ut12);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tai1 += s_tai1, tai2 += s_tai2, dta += s_dta, ut11 += s_ut11, ut12 += s_ut12, c_retval += s_c_retval) {
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _dta = ((double (*))dta);
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _c_retval = eraTaiut1(*_tai1, *_tai2, *_dta, _ut11, _ut12);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_taiutc(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tai1);
+- double (*_tai2);
+- double (*_utc1);
+- double (*_utc2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tai1 += s_tai1, tai2 += s_tai2, utc1 += s_utc1, utc2 += s_utc2, c_retval += s_c_retval) {
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _c_retval = eraTaiutc(*_tai1, *_tai2, _utc1, _utc2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tcbtdb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tcb1 = *args++;
+- npy_intp s_tcb1 = *steps++;
+- char *tcb2 = *args++;
+- npy_intp s_tcb2 = *steps++;
+- char *tdb1 = *args++;
+- npy_intp s_tdb1 = *steps++;
+- char *tdb2 = *args++;
+- npy_intp s_tdb2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tcb1);
+- double (*_tcb2);
+- double (*_tdb1);
+- double (*_tdb2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tcb1 += s_tcb1, tcb2 += s_tcb2, tdb1 += s_tdb1, tdb2 += s_tdb2, c_retval += s_c_retval) {
+- _tcb1 = ((double (*))tcb1);
+- _tcb2 = ((double (*))tcb2);
+- _tdb1 = ((double (*))tdb1);
+- _tdb2 = ((double (*))tdb2);
+- _c_retval = eraTcbtdb(*_tcb1, *_tcb2, _tdb1, _tdb2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tcgtt(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tcg1 = *args++;
+- npy_intp s_tcg1 = *steps++;
+- char *tcg2 = *args++;
+- npy_intp s_tcg2 = *steps++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tcg1);
+- double (*_tcg2);
+- double (*_tt1);
+- double (*_tt2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tcg1 += s_tcg1, tcg2 += s_tcg2, tt1 += s_tt1, tt2 += s_tt2, c_retval += s_c_retval) {
+- _tcg1 = ((double (*))tcg1);
+- _tcg2 = ((double (*))tcg2);
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _c_retval = eraTcgtt(*_tcg1, *_tcg2, _tt1, _tt2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tdbtcb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tdb1 = *args++;
+- npy_intp s_tdb1 = *steps++;
+- char *tdb2 = *args++;
+- npy_intp s_tdb2 = *steps++;
+- char *tcb1 = *args++;
+- npy_intp s_tcb1 = *steps++;
+- char *tcb2 = *args++;
+- npy_intp s_tcb2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tdb1);
+- double (*_tdb2);
+- double (*_tcb1);
+- double (*_tcb2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tdb1 += s_tdb1, tdb2 += s_tdb2, tcb1 += s_tcb1, tcb2 += s_tcb2, c_retval += s_c_retval) {
+- _tdb1 = ((double (*))tdb1);
+- _tdb2 = ((double (*))tdb2);
+- _tcb1 = ((double (*))tcb1);
+- _tcb2 = ((double (*))tcb2);
+- _c_retval = eraTdbtcb(*_tdb1, *_tdb2, _tcb1, _tcb2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tdbtt(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tdb1 = *args++;
+- npy_intp s_tdb1 = *steps++;
+- char *tdb2 = *args++;
+- npy_intp s_tdb2 = *steps++;
+- char *dtr = *args++;
+- npy_intp s_dtr = *steps++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tdb1);
+- double (*_tdb2);
+- double (*_dtr);
+- double (*_tt1);
+- double (*_tt2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tdb1 += s_tdb1, tdb2 += s_tdb2, dtr += s_dtr, tt1 += s_tt1, tt2 += s_tt2, c_retval += s_c_retval) {
+- _tdb1 = ((double (*))tdb1);
+- _tdb2 = ((double (*))tdb2);
+- _dtr = ((double (*))dtr);
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _c_retval = eraTdbtt(*_tdb1, *_tdb2, *_dtr, _tt1, _tt2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tttai(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tt1);
+- double (*_tt2);
+- double (*_tai1);
+- double (*_tai2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tt1 += s_tt1, tt2 += s_tt2, tai1 += s_tai1, tai2 += s_tai2, c_retval += s_c_retval) {
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _c_retval = eraTttai(*_tt1, *_tt2, _tai1, _tai2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tttcg(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *tcg1 = *args++;
+- npy_intp s_tcg1 = *steps++;
+- char *tcg2 = *args++;
+- npy_intp s_tcg2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tt1);
+- double (*_tt2);
+- double (*_tcg1);
+- double (*_tcg2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tt1 += s_tt1, tt2 += s_tt2, tcg1 += s_tcg1, tcg2 += s_tcg2, c_retval += s_c_retval) {
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _tcg1 = ((double (*))tcg1);
+- _tcg2 = ((double (*))tcg2);
+- _c_retval = eraTttcg(*_tt1, *_tt2, _tcg1, _tcg2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tttdb(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *dtr = *args++;
+- npy_intp s_dtr = *steps++;
+- char *tdb1 = *args++;
+- npy_intp s_tdb1 = *steps++;
+- char *tdb2 = *args++;
+- npy_intp s_tdb2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tt1);
+- double (*_tt2);
+- double (*_dtr);
+- double (*_tdb1);
+- double (*_tdb2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tt1 += s_tt1, tt2 += s_tt2, dtr += s_dtr, tdb1 += s_tdb1, tdb2 += s_tdb2, c_retval += s_c_retval) {
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _dtr = ((double (*))dtr);
+- _tdb1 = ((double (*))tdb1);
+- _tdb2 = ((double (*))tdb2);
+- _c_retval = eraTttdb(*_tt1, *_tt2, *_dtr, _tdb1, _tdb2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ttut1(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *dt = *args++;
+- npy_intp s_dt = *steps++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_tt1);
+- double (*_tt2);
+- double (*_dt);
+- double (*_ut11);
+- double (*_ut12);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, tt1 += s_tt1, tt2 += s_tt2, dt += s_dt, ut11 += s_ut11, ut12 += s_ut12, c_retval += s_c_retval) {
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _dt = ((double (*))dt);
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _c_retval = eraTtut1(*_tt1, *_tt2, *_dt, _ut11, _ut12);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ut1tai(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *dta = *args++;
+- npy_intp s_dta = *steps++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ut11);
+- double (*_ut12);
+- double (*_dta);
+- double (*_tai1);
+- double (*_tai2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ut11 += s_ut11, ut12 += s_ut12, dta += s_dta, tai1 += s_tai1, tai2 += s_tai2, c_retval += s_c_retval) {
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _dta = ((double (*))dta);
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _c_retval = eraUt1tai(*_ut11, *_ut12, *_dta, _tai1, _tai2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ut1tt(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *dt = *args++;
+- npy_intp s_dt = *steps++;
+- char *tt1 = *args++;
+- npy_intp s_tt1 = *steps++;
+- char *tt2 = *args++;
+- npy_intp s_tt2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ut11);
+- double (*_ut12);
+- double (*_dt);
+- double (*_tt1);
+- double (*_tt2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ut11 += s_ut11, ut12 += s_ut12, dt += s_dt, tt1 += s_tt1, tt2 += s_tt2, c_retval += s_c_retval) {
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _dt = ((double (*))dt);
+- _tt1 = ((double (*))tt1);
+- _tt2 = ((double (*))tt2);
+- _c_retval = eraUt1tt(*_ut11, *_ut12, *_dt, _tt1, _tt2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ut1utc(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ut11);
+- double (*_ut12);
+- double (*_dut1);
+- double (*_utc1);
+- double (*_utc2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ut11 += s_ut11, ut12 += s_ut12, dut1 += s_dut1, utc1 += s_utc1, utc2 += s_utc2, c_retval += s_c_retval) {
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _dut1 = ((double (*))dut1);
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _c_retval = eraUt1utc(*_ut11, *_ut12, *_dut1, _utc1, _utc2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_utctai(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *tai1 = *args++;
+- npy_intp s_tai1 = *steps++;
+- char *tai2 = *args++;
+- npy_intp s_tai2 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_utc1);
+- double (*_utc2);
+- double (*_tai1);
+- double (*_tai2);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, utc1 += s_utc1, utc2 += s_utc2, tai1 += s_tai1, tai2 += s_tai2, c_retval += s_c_retval) {
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _tai1 = ((double (*))tai1);
+- _tai2 = ((double (*))tai2);
+- _c_retval = eraUtctai(*_utc1, *_utc2, _tai1, _tai2);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_utcut1(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *utc1 = *args++;
+- npy_intp s_utc1 = *steps++;
+- char *utc2 = *args++;
+- npy_intp s_utc2 = *steps++;
+- char *dut1 = *args++;
+- npy_intp s_dut1 = *steps++;
+- char *ut11 = *args++;
+- npy_intp s_ut11 = *steps++;
+- char *ut12 = *args++;
+- npy_intp s_ut12 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_utc1);
+- double (*_utc2);
+- double (*_dut1);
+- double (*_ut11);
+- double (*_ut12);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, utc1 += s_utc1, utc2 += s_utc2, dut1 += s_dut1, ut11 += s_ut11, ut12 += s_ut12, c_retval += s_c_retval) {
+- _utc1 = ((double (*))utc1);
+- _utc2 = ((double (*))utc2);
+- _dut1 = ((double (*))dut1);
+- _ut11 = ((double (*))ut11);
+- _ut12 = ((double (*))ut12);
+- _c_retval = eraUtcut1(*_utc1, *_utc2, *_dut1, _ut11, _ut12);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_ae2hd(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *az = *args++;
+- npy_intp s_az = *steps++;
+- char *el = *args++;
+- npy_intp s_el = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *ha = *args++;
+- npy_intp s_ha = *steps++;
+- char *dec = *args++;
+- npy_intp s_dec = *steps++;
+- double (*_az);
+- double (*_el);
+- double (*_phi);
+- double (*_ha);
+- double (*_dec);
+- for (i_o = 0; i_o < n_o;
+- i_o++, az += s_az, el += s_el, phi += s_phi, ha += s_ha, dec += s_dec) {
+- _az = ((double (*))az);
+- _el = ((double (*))el);
+- _phi = ((double (*))phi);
+- _ha = ((double (*))ha);
+- _dec = ((double (*))dec);
+- eraAe2hd(*_az, *_el, *_phi, _ha, _dec);
+- }
+-}
+-
+-static void ufunc_loop_hd2ae(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ha = *args++;
+- npy_intp s_ha = *steps++;
+- char *dec = *args++;
+- npy_intp s_dec = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *az = *args++;
+- npy_intp s_az = *steps++;
+- char *el = *args++;
+- npy_intp s_el = *steps++;
+- double (*_ha);
+- double (*_dec);
+- double (*_phi);
+- double (*_az);
+- double (*_el);
+- for (i_o = 0; i_o < n_o;
+- i_o++, ha += s_ha, dec += s_dec, phi += s_phi, az += s_az, el += s_el) {
+- _ha = ((double (*))ha);
+- _dec = ((double (*))dec);
+- _phi = ((double (*))phi);
+- _az = ((double (*))az);
+- _el = ((double (*))el);
+- eraHd2ae(*_ha, *_dec, *_phi, _az, _el);
+- }
+-}
+-
+-static void ufunc_loop_hd2pa(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ha = *args++;
+- npy_intp s_ha = *steps++;
+- char *dec = *args++;
+- npy_intp s_dec = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_ha);
+- double (*_dec);
+- double (*_phi);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, ha += s_ha, dec += s_dec, phi += s_phi, c_retval += s_c_retval) {
+- _ha = ((double (*))ha);
+- _dec = ((double (*))dec);
+- _phi = ((double (*))phi);
+- _c_retval = eraHd2pa(*_ha, *_dec, *_phi);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tpors(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *a01 = *args++;
+- npy_intp s_a01 = *steps++;
+- char *b01 = *args++;
+- npy_intp s_b01 = *steps++;
+- char *a02 = *args++;
+- npy_intp s_a02 = *steps++;
+- char *b02 = *args++;
+- npy_intp s_b02 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_xi);
+- double (*_eta);
+- double (*_a);
+- double (*_b);
+- double (*_a01);
+- double (*_b01);
+- double (*_a02);
+- double (*_b02);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, xi += s_xi, eta += s_eta, a += s_a, b += s_b, a01 += s_a01, b01 += s_b01, a02 += s_a02, b02 += s_b02, c_retval += s_c_retval) {
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- _a = ((double (*))a);
+- _b = ((double (*))b);
+- _a01 = ((double (*))a01);
+- _b01 = ((double (*))b01);
+- _a02 = ((double (*))a02);
+- _b02 = ((double (*))b02);
+- _c_retval = eraTpors(*_xi, *_eta, *_a, *_b, _a01, _b01, _a02, _b02);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tporv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- char *v01 = *args++;
+- npy_intp s_v01 = *steps++;
+- char *v02 = *args++;
+- npy_intp s_v02 = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_xi);
+- double (*_eta);
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- double b_v01[3];
+- double (*_v01)[3] = &b_v01;
+- double b_v02[3];
+- double (*_v02)[3] = &b_v02;
+- int _c_retval;
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- npy_intp is_v010 = *steps++;
+- int copy_v01 = (is_v010 != sizeof(double));
+- npy_intp is_v020 = *steps++;
+- int copy_v02 = (is_v020 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, xi += s_xi, eta += s_eta, v += s_v, v01 += s_v01, v02 += s_v02, c_retval += s_c_retval) {
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- if (copy_v) {
+- copy_to_double3(v, is_v0, *_v);
+- }
+- else {
+- _v = ((double (*)[3])v);
+- }
+- if (!copy_v01) {
+- _v01 = ((double (*)[3])v01);
+- }
+- if (!copy_v02) {
+- _v02 = ((double (*)[3])v02);
+- }
+- _c_retval = eraTporv(*_xi, *_eta, *_v, *_v01, *_v02);
+- *((int *)c_retval) = _c_retval;
+- if (copy_v01) {
+- copy_from_double3(v01, is_v010, *_v01);
+- }
+- if (copy_v02) {
+- copy_from_double3(v02, is_v020, *_v02);
+- }
+- }
+-}
+-
+-static void ufunc_loop_tpsts(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *a0 = *args++;
+- npy_intp s_a0 = *steps++;
+- char *b0 = *args++;
+- npy_intp s_b0 = *steps++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- double (*_xi);
+- double (*_eta);
+- double (*_a0);
+- double (*_b0);
+- double (*_a);
+- double (*_b);
+- for (i_o = 0; i_o < n_o;
+- i_o++, xi += s_xi, eta += s_eta, a0 += s_a0, b0 += s_b0, a += s_a, b += s_b) {
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- _a0 = ((double (*))a0);
+- _b0 = ((double (*))b0);
+- _a = ((double (*))a);
+- _b = ((double (*))b);
+- eraTpsts(*_xi, *_eta, *_a0, *_b0, _a, _b);
+- }
+-}
+-
+-static void ufunc_loop_tpstv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *v0 = *args++;
+- npy_intp s_v0 = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- double (*_xi);
+- double (*_eta);
+- double b_v0[3];
+- double (*_v0)[3] = &b_v0;
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- npy_intp is_v00 = *steps++;
+- int copy_v0 = (is_v00 != sizeof(double));
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, xi += s_xi, eta += s_eta, v0 += s_v0, v += s_v) {
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- if (copy_v0) {
+- copy_to_double3(v0, is_v00, *_v0);
+- }
+- else {
+- _v0 = ((double (*)[3])v0);
+- }
+- if (!copy_v) {
+- _v = ((double (*)[3])v);
+- }
+- eraTpstv(*_xi, *_eta, *_v0, *_v);
+- if (copy_v) {
+- copy_from_double3(v, is_v0, *_v);
+- }
+- }
+-}
+-
+-static void ufunc_loop_tpxes(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *a0 = *args++;
+- npy_intp s_a0 = *steps++;
+- char *b0 = *args++;
+- npy_intp s_b0 = *steps++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_a);
+- double (*_b);
+- double (*_a0);
+- double (*_b0);
+- double (*_xi);
+- double (*_eta);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, a0 += s_a0, b0 += s_b0, xi += s_xi, eta += s_eta, c_retval += s_c_retval) {
+- _a = ((double (*))a);
+- _b = ((double (*))b);
+- _a0 = ((double (*))a0);
+- _b0 = ((double (*))b0);
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- _c_retval = eraTpxes(*_a, *_b, *_a0, *_b0, _xi, _eta);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tpxev(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- char *v0 = *args++;
+- npy_intp s_v0 = *steps++;
+- char *xi = *args++;
+- npy_intp s_xi = *steps++;
+- char *eta = *args++;
+- npy_intp s_eta = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- double b_v0[3];
+- double (*_v0)[3] = &b_v0;
+- double (*_xi);
+- double (*_eta);
+- int _c_retval;
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- npy_intp is_v00 = *steps++;
+- int copy_v0 = (is_v00 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, v += s_v, v0 += s_v0, xi += s_xi, eta += s_eta, c_retval += s_c_retval) {
+- if (copy_v) {
+- copy_to_double3(v, is_v0, *_v);
+- }
+- else {
+- _v = ((double (*)[3])v);
+- }
+- if (copy_v0) {
+- copy_to_double3(v0, is_v00, *_v0);
+- }
+- else {
+- _v0 = ((double (*)[3])v0);
+- }
+- _xi = ((double (*))xi);
+- _eta = ((double (*))eta);
+- _c_retval = eraTpxev(*_v, *_v0, _xi, _eta);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_a2af(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ndp = *args++;
+- npy_intp s_ndp = *steps++;
+- char *angle = *args++;
+- npy_intp s_angle = *steps++;
+- char *sign = *args++;
+- npy_intp s_sign = *steps++;
+- char *idmsf = *args++;
+- npy_intp s_idmsf = *steps++;
+- int (*_ndp);
+- double (*_angle);
+- char (*_sign);
+- int (*_idmsf)[4];
+- for (i_o = 0; i_o < n_o;
+- i_o++, ndp += s_ndp, angle += s_angle, sign += s_sign, idmsf += s_idmsf) {
+- _ndp = ((int (*))ndp);
+- _angle = ((double (*))angle);
+- _sign = ((char (*))sign);
+- _idmsf = ((int (*)[4])idmsf);
+- eraA2af(*_ndp, *_angle, _sign, *_idmsf);
+- }
+-}
+-
+-static void ufunc_loop_a2tf(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ndp = *args++;
+- npy_intp s_ndp = *steps++;
+- char *angle = *args++;
+- npy_intp s_angle = *steps++;
+- char *sign = *args++;
+- npy_intp s_sign = *steps++;
+- char *ihmsf = *args++;
+- npy_intp s_ihmsf = *steps++;
+- int (*_ndp);
+- double (*_angle);
+- char (*_sign);
+- int (*_ihmsf)[4];
+- for (i_o = 0; i_o < n_o;
+- i_o++, ndp += s_ndp, angle += s_angle, sign += s_sign, ihmsf += s_ihmsf) {
+- _ndp = ((int (*))ndp);
+- _angle = ((double (*))angle);
+- _sign = ((char (*))sign);
+- _ihmsf = ((int (*)[4])ihmsf);
+- eraA2tf(*_ndp, *_angle, _sign, *_ihmsf);
+- }
+-}
+-
+-static void ufunc_loop_af2a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *ideg = *args++;
+- npy_intp s_ideg = *steps++;
+- char *iamin = *args++;
+- npy_intp s_iamin = *steps++;
+- char *asec = *args++;
+- npy_intp s_asec = *steps++;
+- char *rad = *args++;
+- npy_intp s_rad = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- char (*_s);
+- int (*_ideg);
+- int (*_iamin);
+- double (*_asec);
+- double (*_rad);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, s += s_s, ideg += s_ideg, iamin += s_iamin, asec += s_asec, rad += s_rad, c_retval += s_c_retval) {
+- _s = ((char (*))s);
+- _ideg = ((int (*))ideg);
+- _iamin = ((int (*))iamin);
+- _asec = ((double (*))asec);
+- _rad = ((double (*))rad);
+- _c_retval = eraAf2a(*_s, *_ideg, *_iamin, *_asec, _rad);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_anp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_a);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, c_retval += s_c_retval) {
+- _a = ((double (*))a);
+- _c_retval = eraAnp(*_a);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_anpm(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_a);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, c_retval += s_c_retval) {
+- _a = ((double (*))a);
+- _c_retval = eraAnpm(*_a);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_d2tf(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *ndp = *args++;
+- npy_intp s_ndp = *steps++;
+- char *days = *args++;
+- npy_intp s_days = *steps++;
+- char *sign = *args++;
+- npy_intp s_sign = *steps++;
+- char *ihmsf = *args++;
+- npy_intp s_ihmsf = *steps++;
+- int (*_ndp);
+- double (*_days);
+- char (*_sign);
+- int (*_ihmsf)[4];
+- for (i_o = 0; i_o < n_o;
+- i_o++, ndp += s_ndp, days += s_days, sign += s_sign, ihmsf += s_ihmsf) {
+- _ndp = ((int (*))ndp);
+- _days = ((double (*))days);
+- _sign = ((char (*))sign);
+- _ihmsf = ((int (*)[4])ihmsf);
+- eraD2tf(*_ndp, *_days, _sign, *_ihmsf);
+- }
+-}
+-
+-static void ufunc_loop_tf2a(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *ihour = *args++;
+- npy_intp s_ihour = *steps++;
+- char *imin = *args++;
+- npy_intp s_imin = *steps++;
+- char *sec = *args++;
+- npy_intp s_sec = *steps++;
+- char *rad = *args++;
+- npy_intp s_rad = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- char (*_s);
+- int (*_ihour);
+- int (*_imin);
+- double (*_sec);
+- double (*_rad);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, s += s_s, ihour += s_ihour, imin += s_imin, sec += s_sec, rad += s_rad, c_retval += s_c_retval) {
+- _s = ((char (*))s);
+- _ihour = ((int (*))ihour);
+- _imin = ((int (*))imin);
+- _sec = ((double (*))sec);
+- _rad = ((double (*))rad);
+- _c_retval = eraTf2a(*_s, *_ihour, *_imin, *_sec, _rad);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_tf2d(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *ihour = *args++;
+- npy_intp s_ihour = *steps++;
+- char *imin = *args++;
+- npy_intp s_imin = *steps++;
+- char *sec = *args++;
+- npy_intp s_sec = *steps++;
+- char *days = *args++;
+- npy_intp s_days = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- char (*_s);
+- int (*_ihour);
+- int (*_imin);
+- double (*_sec);
+- double (*_days);
+- int _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, s += s_s, ihour += s_ihour, imin += s_imin, sec += s_sec, days += s_days, c_retval += s_c_retval) {
+- _s = ((char (*))s);
+- _ihour = ((int (*))ihour);
+- _imin = ((int (*))imin);
+- _sec = ((double (*))sec);
+- _days = ((double (*))days);
+- _c_retval = eraTf2d(*_s, *_ihour, *_imin, *_sec, _days);
+- *((int *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_rx(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *r_in = *args++;
+- npy_intp s_r_in = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double (*_phi);
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r_in0 = *steps++;
+- npy_intp is_r_in1 = *steps++;
+- int copy_r_in = (is_r_in1 != sizeof(double) &&
+- is_r_in0 != 3 * sizeof(double));
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, phi += s_phi, r += s_r, r_in += s_r_in) {
+- _phi = ((double (*))phi);
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- if (copy_r_in || r != r_in) {
+- copy_to_double33(r_in, is_r_in0, is_r_in1, *_r);
+- }
+- eraRx(*_phi, *_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ry(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *r_in = *args++;
+- npy_intp s_r_in = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double (*_theta);
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r_in0 = *steps++;
+- npy_intp is_r_in1 = *steps++;
+- int copy_r_in = (is_r_in1 != sizeof(double) &&
+- is_r_in0 != 3 * sizeof(double));
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, theta += s_theta, r += s_r, r_in += s_r_in) {
+- _theta = ((double (*))theta);
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- if (copy_r_in || r != r_in) {
+- copy_to_double33(r_in, is_r_in0, is_r_in1, *_r);
+- }
+- eraRy(*_theta, *_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_rz(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *psi = *args++;
+- npy_intp s_psi = *steps++;
+- char *r_in = *args++;
+- npy_intp s_r_in = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double (*_psi);
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r_in0 = *steps++;
+- npy_intp is_r_in1 = *steps++;
+- int copy_r_in = (is_r_in1 != sizeof(double) &&
+- is_r_in0 != 3 * sizeof(double));
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, psi += s_psi, r += s_r, r_in += s_r_in) {
+- _psi = ((double (*))psi);
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- if (copy_r_in || r != r_in) {
+- copy_to_double33(r_in, is_r_in0, is_r_in1, *_r);
+- }
+- eraRz(*_psi, *_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_cp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *c = *args++;
+- npy_intp s_c = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_c[3];
+- double (*_c)[3] = &b_c;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_c0 = *steps++;
+- int copy_c = (is_c0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, c += s_c) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (!copy_c) {
+- _c = ((double (*)[3])c);
+- }
+- eraCp(*_p, *_c);
+- if (copy_c) {
+- copy_from_double3(c, is_c0, *_c);
+- }
+- }
+-}
+-
+-static void ufunc_loop_cpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *c = *args++;
+- npy_intp s_c = *steps++;
+- double (*_pv)[2][3];
+- double (*_c)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, c += s_c) {
+- _pv = ((double (*)[2][3])pv);
+- _c = ((double (*)[2][3])c);
+- eraCpv(*_pv, *_c);
+- }
+-}
+-
+-static void ufunc_loop_cr(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *c = *args++;
+- npy_intp s_c = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double b_c[3][3];
+- double (*_c)[3][3] = &b_c;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- npy_intp is_c0 = *steps++;
+- npy_intp is_c1 = *steps++;
+- int copy_c = (is_c1 != sizeof(double) &&
+- is_c0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, c += s_c) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- if (!copy_c) {
+- _c = ((double (*)[3][3])c);
+- }
+- eraCr(*_r, *_c);
+- if (copy_c) {
+- copy_from_double33(c, is_c0, is_c1, *_c);
+- }
+- }
+-}
+-
+-static void ufunc_loop_p2pv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double (*_pv)[2][3];
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, pv += s_pv) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- _pv = ((double (*)[2][3])pv);
+- eraP2pv(*_p, *_pv);
+- }
+-}
+-
+-static void ufunc_loop_pv2p(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- double (*_pv)[2][3];
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, p += s_p) {
+- _pv = ((double (*)[2][3])pv);
+- if (!copy_p) {
+- _p = ((double (*)[3])p);
+- }
+- eraPv2p(*_pv, *_p);
+- if (copy_p) {
+- copy_from_double3(p, is_p0, *_p);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ir(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r) {
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- eraIr(*_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_zp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p) {
+- if (!copy_p) {
+- _p = ((double (*)[3])p);
+- }
+- eraZp(*_p);
+- if (copy_p) {
+- copy_from_double3(p, is_p0, *_p);
+- }
+- }
+-}
+-
+-static void ufunc_loop_zpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- double (*_pv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv) {
+- _pv = ((double (*)[2][3])pv);
+- eraZpv(*_pv);
+- }
+-}
+-
+-static void ufunc_loop_zr(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r) {
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- eraZr(*_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_rxr(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *atb = *args++;
+- npy_intp s_atb = *steps++;
+- double b_a[3][3];
+- double (*_a)[3][3] = &b_a;
+- double b_b[3][3];
+- double (*_b)[3][3] = &b_b;
+- double b_atb[3][3];
+- double (*_atb)[3][3] = &b_atb;
+- npy_intp is_a0 = *steps++;
+- npy_intp is_a1 = *steps++;
+- int copy_a = (is_a1 != sizeof(double) &&
+- is_a0 != 3 * sizeof(double));
+- npy_intp is_b0 = *steps++;
+- npy_intp is_b1 = *steps++;
+- int copy_b = (is_b1 != sizeof(double) &&
+- is_b0 != 3 * sizeof(double));
+- npy_intp is_atb0 = *steps++;
+- npy_intp is_atb1 = *steps++;
+- int copy_atb = (is_atb1 != sizeof(double) &&
+- is_atb0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, atb += s_atb) {
+- if (copy_a) {
+- copy_to_double33(a, is_a0, is_a1, *_a);
+- }
+- else {
+- _a = ((double (*)[3][3])a);
+- }
+- if (copy_b) {
+- copy_to_double33(b, is_b0, is_b1, *_b);
+- }
+- else {
+- _b = ((double (*)[3][3])b);
+- }
+- if (!copy_atb) {
+- _atb = ((double (*)[3][3])atb);
+- }
+- eraRxr(*_a, *_b, *_atb);
+- if (copy_atb) {
+- copy_from_double33(atb, is_atb0, is_atb1, *_atb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_tr(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *rt = *args++;
+- npy_intp s_rt = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double b_rt[3][3];
+- double (*_rt)[3][3] = &b_rt;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- npy_intp is_rt0 = *steps++;
+- npy_intp is_rt1 = *steps++;
+- int copy_rt = (is_rt1 != sizeof(double) &&
+- is_rt0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, rt += s_rt) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- if (!copy_rt) {
+- _rt = ((double (*)[3][3])rt);
+- }
+- eraTr(*_r, *_rt);
+- if (copy_rt) {
+- copy_from_double33(rt, is_rt0, is_rt1, *_rt);
+- }
+- }
+-}
+-
+-static void ufunc_loop_rxp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *rp = *args++;
+- npy_intp s_rp = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_rp[3];
+- double (*_rp)[3] = &b_rp;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_rp0 = *steps++;
+- int copy_rp = (is_rp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, p += s_p, rp += s_rp) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (!copy_rp) {
+- _rp = ((double (*)[3])rp);
+- }
+- eraRxp(*_r, *_p, *_rp);
+- if (copy_rp) {
+- copy_from_double3(rp, is_rp0, *_rp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_rxpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *rpv = *args++;
+- npy_intp s_rpv = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double (*_pv)[2][3];
+- double (*_rpv)[2][3];
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, pv += s_pv, rpv += s_rpv) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- _pv = ((double (*)[2][3])pv);
+- _rpv = ((double (*)[2][3])rpv);
+- eraRxpv(*_r, *_pv, *_rpv);
+- }
+-}
+-
+-static void ufunc_loop_trxp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *trp = *args++;
+- npy_intp s_trp = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_trp[3];
+- double (*_trp)[3] = &b_trp;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_trp0 = *steps++;
+- int copy_trp = (is_trp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, p += s_p, trp += s_trp) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (!copy_trp) {
+- _trp = ((double (*)[3])trp);
+- }
+- eraTrxp(*_r, *_p, *_trp);
+- if (copy_trp) {
+- copy_from_double3(trp, is_trp0, *_trp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_trxpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *trpv = *args++;
+- npy_intp s_trpv = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double (*_pv)[2][3];
+- double (*_trpv)[2][3];
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, pv += s_pv, trpv += s_trpv) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- _pv = ((double (*)[2][3])pv);
+- _trpv = ((double (*)[2][3])trpv);
+- eraTrxpv(*_r, *_pv, *_trpv);
+- }
+-}
+-
+-static void ufunc_loop_rm2v(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *w = *args++;
+- npy_intp s_w = *steps++;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- double b_w[3];
+- double (*_w)[3] = &b_w;
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- npy_intp is_w0 = *steps++;
+- int copy_w = (is_w0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, r += s_r, w += s_w) {
+- if (copy_r) {
+- copy_to_double33(r, is_r0, is_r1, *_r);
+- }
+- else {
+- _r = ((double (*)[3][3])r);
+- }
+- if (!copy_w) {
+- _w = ((double (*)[3])w);
+- }
+- eraRm2v(*_r, *_w);
+- if (copy_w) {
+- copy_from_double3(w, is_w0, *_w);
+- }
+- }
+-}
+-
+-static void ufunc_loop_rv2m(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *w = *args++;
+- npy_intp s_w = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double b_w[3];
+- double (*_w)[3] = &b_w;
+- double b_r[3][3];
+- double (*_r)[3][3] = &b_r;
+- npy_intp is_w0 = *steps++;
+- int copy_w = (is_w0 != sizeof(double));
+- npy_intp is_r0 = *steps++;
+- npy_intp is_r1 = *steps++;
+- int copy_r = (is_r1 != sizeof(double) &&
+- is_r0 != 3 * sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, w += s_w, r += s_r) {
+- if (copy_w) {
+- copy_to_double3(w, is_w0, *_w);
+- }
+- else {
+- _w = ((double (*)[3])w);
+- }
+- if (!copy_r) {
+- _r = ((double (*)[3][3])r);
+- }
+- eraRv2m(*_w, *_r);
+- if (copy_r) {
+- copy_from_double33(r, is_r0, is_r1, *_r);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pap(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double _c_retval;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, c_retval += s_c_retval) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- _c_retval = eraPap(*_a, *_b);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_pas(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *al = *args++;
+- npy_intp s_al = *steps++;
+- char *ap = *args++;
+- npy_intp s_ap = *steps++;
+- char *bl = *args++;
+- npy_intp s_bl = *steps++;
+- char *bp = *args++;
+- npy_intp s_bp = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_al);
+- double (*_ap);
+- double (*_bl);
+- double (*_bp);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, al += s_al, ap += s_ap, bl += s_bl, bp += s_bp, c_retval += s_c_retval) {
+- _al = ((double (*))al);
+- _ap = ((double (*))ap);
+- _bl = ((double (*))bl);
+- _bp = ((double (*))bp);
+- _c_retval = eraPas(*_al, *_ap, *_bl, *_bp);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_sepp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double _c_retval;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, c_retval += s_c_retval) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- _c_retval = eraSepp(*_a, *_b);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_seps(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *al = *args++;
+- npy_intp s_al = *steps++;
+- char *ap = *args++;
+- npy_intp s_ap = *steps++;
+- char *bl = *args++;
+- npy_intp s_bl = *steps++;
+- char *bp = *args++;
+- npy_intp s_bp = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double (*_al);
+- double (*_ap);
+- double (*_bl);
+- double (*_bp);
+- double _c_retval;
+- for (i_o = 0; i_o < n_o;
+- i_o++, al += s_al, ap += s_ap, bl += s_bl, bp += s_bp, c_retval += s_c_retval) {
+- _al = ((double (*))al);
+- _ap = ((double (*))ap);
+- _bl = ((double (*))bl);
+- _bp = ((double (*))bp);
+- _c_retval = eraSeps(*_al, *_ap, *_bl, *_bp);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_c2s(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double (*_theta);
+- double (*_phi);
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, theta += s_theta, phi += s_phi) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- eraC2s(*_p, _theta, _phi);
+- }
+-}
+-
+-static void ufunc_loop_p2s(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double (*_theta);
+- double (*_phi);
+- double (*_r);
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, theta += s_theta, phi += s_phi, r += s_r) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- _r = ((double (*))r);
+- eraP2s(*_p, _theta, _phi, _r);
+- }
+-}
+-
+-static void ufunc_loop_pv2s(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *td = *args++;
+- npy_intp s_td = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *rd = *args++;
+- npy_intp s_rd = *steps++;
+- double (*_pv)[2][3];
+- double (*_theta);
+- double (*_phi);
+- double (*_r);
+- double (*_td);
+- double (*_pd);
+- double (*_rd);
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, theta += s_theta, phi += s_phi, r += s_r, td += s_td, pd += s_pd, rd += s_rd) {
+- _pv = ((double (*)[2][3])pv);
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- _r = ((double (*))r);
+- _td = ((double (*))td);
+- _pd = ((double (*))pd);
+- _rd = ((double (*))rd);
+- eraPv2s(*_pv, _theta, _phi, _r, _td, _pd, _rd);
+- }
+-}
+-
+-static void ufunc_loop_s2c(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *c = *args++;
+- npy_intp s_c = *steps++;
+- double (*_theta);
+- double (*_phi);
+- double b_c[3];
+- double (*_c)[3] = &b_c;
+- npy_intp is_c0 = *steps++;
+- int copy_c = (is_c0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, theta += s_theta, phi += s_phi, c += s_c) {
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- if (!copy_c) {
+- _c = ((double (*)[3])c);
+- }
+- eraS2c(*_theta, *_phi, *_c);
+- if (copy_c) {
+- copy_from_double3(c, is_c0, *_c);
+- }
+- }
+-}
+-
+-static void ufunc_loop_s2p(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- double (*_theta);
+- double (*_phi);
+- double (*_r);
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, theta += s_theta, phi += s_phi, r += s_r, p += s_p) {
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- _r = ((double (*))r);
+- if (!copy_p) {
+- _p = ((double (*)[3])p);
+- }
+- eraS2p(*_theta, *_phi, *_r, *_p);
+- if (copy_p) {
+- copy_from_double3(p, is_p0, *_p);
+- }
+- }
+-}
+-
+-static void ufunc_loop_s2pv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *theta = *args++;
+- npy_intp s_theta = *steps++;
+- char *phi = *args++;
+- npy_intp s_phi = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *td = *args++;
+- npy_intp s_td = *steps++;
+- char *pd = *args++;
+- npy_intp s_pd = *steps++;
+- char *rd = *args++;
+- npy_intp s_rd = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- double (*_theta);
+- double (*_phi);
+- double (*_r);
+- double (*_td);
+- double (*_pd);
+- double (*_rd);
+- double (*_pv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, theta += s_theta, phi += s_phi, r += s_r, td += s_td, pd += s_pd, rd += s_rd, pv += s_pv) {
+- _theta = ((double (*))theta);
+- _phi = ((double (*))phi);
+- _r = ((double (*))r);
+- _td = ((double (*))td);
+- _pd = ((double (*))pd);
+- _rd = ((double (*))rd);
+- _pv = ((double (*)[2][3])pv);
+- eraS2pv(*_theta, *_phi, *_r, *_td, *_pd, *_rd, *_pv);
+- }
+-}
+-
+-static void ufunc_loop_pdp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double _c_retval;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, c_retval += s_c_retval) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- _c_retval = eraPdp(*_a, *_b);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_pm(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *c_retval = *args++;
+- npy_intp s_c_retval = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double _c_retval;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, c_retval += s_c_retval) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- _c_retval = eraPm(*_p);
+- *((double *)c_retval) = _c_retval;
+- }
+-}
+-
+-static void ufunc_loop_pmp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *amb = *args++;
+- npy_intp s_amb = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double b_amb[3];
+- double (*_amb)[3] = &b_amb;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- npy_intp is_amb0 = *steps++;
+- int copy_amb = (is_amb0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, amb += s_amb) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- if (!copy_amb) {
+- _amb = ((double (*)[3])amb);
+- }
+- eraPmp(*_a, *_b, *_amb);
+- if (copy_amb) {
+- copy_from_double3(amb, is_amb0, *_amb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pn(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *u = *args++;
+- npy_intp s_u = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double (*_r);
+- double b_u[3];
+- double (*_u)[3] = &b_u;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_u0 = *steps++;
+- int copy_u = (is_u0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, r += s_r, u += s_u) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- _r = ((double (*))r);
+- if (!copy_u) {
+- _u = ((double (*)[3])u);
+- }
+- eraPn(*_p, _r, *_u);
+- if (copy_u) {
+- copy_from_double3(u, is_u0, *_u);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ppp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *apb = *args++;
+- npy_intp s_apb = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double b_apb[3];
+- double (*_apb)[3] = &b_apb;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- npy_intp is_apb0 = *steps++;
+- int copy_apb = (is_apb0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, apb += s_apb) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- if (!copy_apb) {
+- _apb = ((double (*)[3])apb);
+- }
+- eraPpp(*_a, *_b, *_apb);
+- if (copy_apb) {
+- copy_from_double3(apb, is_apb0, *_apb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_ppsp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *apsb = *args++;
+- npy_intp s_apsb = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double (*_s);
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double b_apsb[3];
+- double (*_apsb)[3] = &b_apsb;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- npy_intp is_apsb0 = *steps++;
+- int copy_apsb = (is_apsb0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, s += s_s, b += s_b, apsb += s_apsb) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- _s = ((double (*))s);
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- if (!copy_apsb) {
+- _apsb = ((double (*)[3])apsb);
+- }
+- eraPpsp(*_a, *_s, *_b, *_apsb);
+- if (copy_apsb) {
+- copy_from_double3(apsb, is_apsb0, *_apsb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pvdpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *adb = *args++;
+- npy_intp s_adb = *steps++;
+- double (*_a)[2][3];
+- double (*_b)[2][3];
+- double (*_adb)[2];
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, adb += s_adb) {
+- _a = ((double (*)[2][3])a);
+- _b = ((double (*)[2][3])b);
+- _adb = ((double (*)[2])adb);
+- eraPvdpv(*_a, *_b, *_adb);
+- }
+-}
+-
+-static void ufunc_loop_pvm(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *r = *args++;
+- npy_intp s_r = *steps++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- double (*_pv)[2][3];
+- double (*_r);
+- double (*_s);
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, r += s_r, s += s_s) {
+- _pv = ((double (*)[2][3])pv);
+- _r = ((double (*))r);
+- _s = ((double (*))s);
+- eraPvm(*_pv, _r, _s);
+- }
+-}
+-
+-static void ufunc_loop_pvmpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *amb = *args++;
+- npy_intp s_amb = *steps++;
+- double (*_a)[2][3];
+- double (*_b)[2][3];
+- double (*_amb)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, amb += s_amb) {
+- _a = ((double (*)[2][3])a);
+- _b = ((double (*)[2][3])b);
+- _amb = ((double (*)[2][3])amb);
+- eraPvmpv(*_a, *_b, *_amb);
+- }
+-}
+-
+-static void ufunc_loop_pvppv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *apb = *args++;
+- npy_intp s_apb = *steps++;
+- double (*_a)[2][3];
+- double (*_b)[2][3];
+- double (*_apb)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, apb += s_apb) {
+- _a = ((double (*)[2][3])a);
+- _b = ((double (*)[2][3])b);
+- _apb = ((double (*)[2][3])apb);
+- eraPvppv(*_a, *_b, *_apb);
+- }
+-}
+-
+-static void ufunc_loop_pvu(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dt = *args++;
+- npy_intp s_dt = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *upv = *args++;
+- npy_intp s_upv = *steps++;
+- double (*_dt);
+- double (*_pv)[2][3];
+- double (*_upv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, dt += s_dt, pv += s_pv, upv += s_upv) {
+- _dt = ((double (*))dt);
+- _pv = ((double (*)[2][3])pv);
+- _upv = ((double (*)[2][3])upv);
+- eraPvu(*_dt, *_pv, *_upv);
+- }
+-}
+-
+-static void ufunc_loop_pvup(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *dt = *args++;
+- npy_intp s_dt = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- double (*_dt);
+- double (*_pv)[2][3];
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, dt += s_dt, pv += s_pv, p += s_p) {
+- _dt = ((double (*))dt);
+- _pv = ((double (*)[2][3])pv);
+- if (!copy_p) {
+- _p = ((double (*)[3])p);
+- }
+- eraPvup(*_dt, *_pv, *_p);
+- if (copy_p) {
+- copy_from_double3(p, is_p0, *_p);
+- }
+- }
+-}
+-
+-static void ufunc_loop_pvxpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *axb = *args++;
+- npy_intp s_axb = *steps++;
+- double (*_a)[2][3];
+- double (*_b)[2][3];
+- double (*_axb)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, axb += s_axb) {
+- _a = ((double (*)[2][3])a);
+- _b = ((double (*)[2][3])b);
+- _axb = ((double (*)[2][3])axb);
+- eraPvxpv(*_a, *_b, *_axb);
+- }
+-}
+-
+-static void ufunc_loop_pxp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *a = *args++;
+- npy_intp s_a = *steps++;
+- char *b = *args++;
+- npy_intp s_b = *steps++;
+- char *axb = *args++;
+- npy_intp s_axb = *steps++;
+- double b_a[3];
+- double (*_a)[3] = &b_a;
+- double b_b[3];
+- double (*_b)[3] = &b_b;
+- double b_axb[3];
+- double (*_axb)[3] = &b_axb;
+- npy_intp is_a0 = *steps++;
+- int copy_a = (is_a0 != sizeof(double));
+- npy_intp is_b0 = *steps++;
+- int copy_b = (is_b0 != sizeof(double));
+- npy_intp is_axb0 = *steps++;
+- int copy_axb = (is_axb0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, a += s_a, b += s_b, axb += s_axb) {
+- if (copy_a) {
+- copy_to_double3(a, is_a0, *_a);
+- }
+- else {
+- _a = ((double (*)[3])a);
+- }
+- if (copy_b) {
+- copy_to_double3(b, is_b0, *_b);
+- }
+- else {
+- _b = ((double (*)[3])b);
+- }
+- if (!copy_axb) {
+- _axb = ((double (*)[3])axb);
+- }
+- eraPxp(*_a, *_b, *_axb);
+- if (copy_axb) {
+- copy_from_double3(axb, is_axb0, *_axb);
+- }
+- }
+-}
+-
+-static void ufunc_loop_s2xpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s1 = *args++;
+- npy_intp s_s1 = *steps++;
+- char *s2 = *args++;
+- npy_intp s_s2 = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *spv = *args++;
+- npy_intp s_spv = *steps++;
+- double (*_s1);
+- double (*_s2);
+- double (*_pv)[2][3];
+- double (*_spv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, s1 += s_s1, s2 += s_s2, pv += s_pv, spv += s_spv) {
+- _s1 = ((double (*))s1);
+- _s2 = ((double (*))s2);
+- _pv = ((double (*)[2][3])pv);
+- _spv = ((double (*)[2][3])spv);
+- eraS2xpv(*_s1, *_s2, *_pv, *_spv);
+- }
+-}
+-
+-static void ufunc_loop_sxp(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *sp = *args++;
+- npy_intp s_sp = *steps++;
+- double (*_s);
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_sp[3];
+- double (*_sp)[3] = &b_sp;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_sp0 = *steps++;
+- int copy_sp = (is_sp0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, s += s_s, p += s_p, sp += s_sp) {
+- _s = ((double (*))s);
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (!copy_sp) {
+- _sp = ((double (*)[3])sp);
+- }
+- eraSxp(*_s, *_p, *_sp);
+- if (copy_sp) {
+- copy_from_double3(sp, is_sp0, *_sp);
+- }
+- }
+-}
+-
+-static void ufunc_loop_sxpv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *s = *args++;
+- npy_intp s_s = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *spv = *args++;
+- npy_intp s_spv = *steps++;
+- double (*_s);
+- double (*_pv)[2][3];
+- double (*_spv)[2][3];
+- for (i_o = 0; i_o < n_o;
+- i_o++, s += s_s, pv += s_pv, spv += s_spv) {
+- _s = ((double (*))s);
+- _pv = ((double (*)[2][3])pv);
+- _spv = ((double (*)[2][3])spv);
+- eraSxpv(*_s, *_pv, *_spv);
+- }
+-}
+-
+-static void ufunc_loop_pav2pv(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- double (*_pv)[2][3];
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, p += s_p, v += s_v, pv += s_pv) {
+- if (copy_p) {
+- copy_to_double3(p, is_p0, *_p);
+- }
+- else {
+- _p = ((double (*)[3])p);
+- }
+- if (copy_v) {
+- copy_to_double3(v, is_v0, *_v);
+- }
+- else {
+- _v = ((double (*)[3])v);
+- }
+- _pv = ((double (*)[2][3])pv);
+- eraPav2pv(*_p, *_v, *_pv);
+- }
+-}
+-
+-static void ufunc_loop_pv2pav(
+- char **args, npy_intp *dimensions, npy_intp* steps, void* data)
+-{
+- npy_intp i_o;
+- npy_intp n_o = *dimensions++;
+- char *pv = *args++;
+- npy_intp s_pv = *steps++;
+- char *p = *args++;
+- npy_intp s_p = *steps++;
+- char *v = *args++;
+- npy_intp s_v = *steps++;
+- double (*_pv)[2][3];
+- double b_p[3];
+- double (*_p)[3] = &b_p;
+- double b_v[3];
+- double (*_v)[3] = &b_v;
+- npy_intp is_p0 = *steps++;
+- int copy_p = (is_p0 != sizeof(double));
+- npy_intp is_v0 = *steps++;
+- int copy_v = (is_v0 != sizeof(double));
+- for (i_o = 0; i_o < n_o;
+- i_o++, pv += s_pv, p += s_p, v += s_v) {
+- _pv = ((double (*)[2][3])pv);
+- if (!copy_p) {
+- _p = ((double (*)[3])p);
+- }
+- if (!copy_v) {
+- _v = ((double (*)[3])v);
+- }
+- eraPv2pav(*_pv, *_p, *_v);
+- if (copy_p) {
+- copy_from_double3(p, is_p0, *_p);
+- }
+- if (copy_v) {
+- copy_from_double3(v, is_v0, *_v);
+- }
+- }
+-}
+-
+-/*
+- * UFUNC LOOP MATCHING HELPERS
+- * All but ufunc_loop_matches are copies of code needed but not exported.
+- */
+-
+-/*
+- * Adjusted version of ufunc_loop_matches from
+- * numpy/core/src/umath/ufunc_type_resolution.c.
+- * Here, we special-case the structured dtype check, only allowing
+- * casting of the same dtype or string. We also do not distinguish
+- * between input and output arguments for casting.
+- */
+-static int
+-ufunc_loop_matches(PyUFuncObject *self,
+- PyArrayObject **op,
+- NPY_CASTING casting,
+- int *types, PyArray_Descr **dtypes)
+-{
+- npy_intp i, nin = self->nin, nop = nin + self->nout;
+- /*
+- * Check if all the inputs can be cast to the types used by this function.
+- */
+- for (i = 0; i < nin; ++i) {
+- PyArray_Descr *op_descr = PyArray_DESCR(op[i]);
+- /*
+- * Check for NPY_VOID with an associated struct dtype.
+- */
+- if (types[i] == NPY_VOID && dtypes != NULL) {
+- int op_descr_type_num = op_descr->type_num;
+- int dtype_elsize = dtypes[i]->elsize;
+- /*
+- * MHvK: we do our own check on casting, since by default
+- * all items can cast to structured dtypes (see gh-11114),
+- * which is not OK. So, we only allow VOID->same VOID,
+- * and STRING -> VOID-of-STRING (which works well; we
+- * recognize VOID-of-STRING by the dtype element size;
+- * it would be rather costly to go look at dtype->fields).
+- */
+- if (op_descr_type_num == NPY_VOID) {
+- /* allow only the same structured to structured */
+- if (!PyArray_EquivTypes(op_descr, dtypes[i])) {
+- return 0;
+- }
+- }
+- else if (dtypes[i]->elsize == 1 || dtypes[i]->elsize == 12) {
+- /* string structured array; string argument is OK */
+- if (!((op_descr_type_num == NPY_STRING &&
+- op_descr->elsize <= dtype_elsize) ||
+- (op_descr_type_num == NPY_UNICODE &&
+- op_descr->elsize >> 2 <= dtype_elsize))) {
+- return 0;
+- }
+- }
+- else {
+- return 0;
+- }
+- }
+- else { /* non-void function argument */
+- PyArray_Descr *tmp = PyArray_DescrFromType(types[i]);
+- if (tmp == NULL) {
+- return -1;
+- }
+- if (!PyArray_CanCastTypeTo(op_descr, tmp, casting)) {
+- Py_DECREF(tmp);
+- return 0;
+- }
+- Py_DECREF(tmp);
+- }
+- }
+- /*
+- * All inputs were ok; now check casting back to the outputs.
+- * MHvK: Since no casting from structured to non-structured is
+- * possible, no changes needed here.
+- */
+- for (i = nin; i < nop; ++i) {
+- if (op[i] != NULL) {
+- PyArray_Descr *tmp = PyArray_DescrFromType(types[i]);
+- if (tmp == NULL) {
+- return -1;
+- }
+- if (!PyArray_CanCastTypeTo(tmp, PyArray_DESCR(op[i]),
+- casting)) {
+- Py_DECREF(tmp);
+- return 0;
+- }
+- Py_DECREF(tmp);
+- }
+- }
+- return 1;
+-}
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since this translation function is not exported.
+- */
+-static const char *
+-npy_casting_to_string(NPY_CASTING casting)
+-{
+- switch (casting) {
+- case NPY_NO_CASTING:
+- return "'no'";
+- case NPY_EQUIV_CASTING:
+- return "'equiv'";
+- case NPY_SAFE_CASTING:
+- return "'safe'";
+- case NPY_SAME_KIND_CASTING:
+- return "'same_kind'";
+- case NPY_UNSAFE_CASTING:
+- return "'unsafe'";
+- default:
+- return "";
+- }
+-}
+-
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since not exported.
+- */
+-static PyArray_Descr *
+-ensure_dtype_nbo(PyArray_Descr *type)
+-{
+- if (PyArray_ISNBO(type->byteorder)) {
+- Py_INCREF(type);
+- return type;
+- }
+- else {
+- return PyArray_DescrNewByteorder(type, NPY_NATIVE);
+- }
+-}
+-
+-/*
+- * Copy from numpy/core/src/umath/ufunc_type_resolution.c,
+- * since not exported.
+- */
+-static int
+-set_ufunc_loop_data_types(PyUFuncObject *self, PyArrayObject **op,
+- PyArray_Descr **out_dtypes,
+- int *type_nums, PyArray_Descr **dtypes)
+-{
+- int i, nin = self->nin, nop = nin + self->nout;
+-
+- /*
+- * Fill the dtypes array.
+- * For outputs,
+- * also search the inputs for a matching type_num to copy
+- * instead of creating a new one, similarly to preserve metadata.
+- **/
+- for (i = 0; i < nop; ++i) {
+- if (dtypes != NULL) {
+- out_dtypes[i] = dtypes[i];
+- Py_XINCREF(out_dtypes[i]);
+- /*
+- * Copy the dtype from 'op' if the type_num matches,
+- * to preserve metadata.
+- */
+- }
+- else if (op[i] != NULL &&
+- PyArray_DESCR(op[i])->type_num == type_nums[i]) {
+- out_dtypes[i] = ensure_dtype_nbo(PyArray_DESCR(op[i]));
+- }
+- /*
+- * For outputs, copy the dtype from op[0] if the type_num
+- * matches, similarly to preserve metdata.
+- */
+- else if (i >= nin && op[0] != NULL &&
+- PyArray_DESCR(op[0])->type_num == type_nums[i]) {
+- out_dtypes[i] = ensure_dtype_nbo(PyArray_DESCR(op[0]));
+- }
+- /* Otherwise create a plain descr from the type number */
+- else {
+- out_dtypes[i] = PyArray_DescrFromType(type_nums[i]);
+- }
+-
+- if (out_dtypes[i] == NULL) {
+- goto fail;
+- }
+- }
+-
+- return 0;
+-
+-fail:
+- while (--i >= 0) {
+- Py_DECREF(out_dtypes[i]);
+- out_dtypes[i] = NULL;
+- }
+- return -1;
+-}
+-
+-/*
+- * UFUNC TYPE RESOLVER
+- *
+- * We provide our own type resolver, since the default one,
+- * PyUFunc_DefaultTypeResolver from
+- * numpy/core/src/umath/ufunc_type_resolution.c, has problems:
+- * 1. It only looks for userloops if any of the operands have a user
+- * type, which does not work if the inputs are normal and no explicit
+- * output is given (see https://github.com/numpy/numpy/issues/11109).
+- * 2. It only allows "safe" casting of inputs, which annoyingly prevents
+- * passing in a python int for int32 input.
+- * The resolver below solves both, and speeds up the process by
+- * explicitly assuming that a ufunc has only one function built in,
+- * either a regular one or a userloop (for structured dtype).
+- *
+- * Combines code from linear_search_type_resolver and
+- * linear_search_userloop_type_resolver from
+- * numpy/core/src/umath/ufunc_type_resolution.c
+- */
+-static int ErfaUFuncTypeResolver(PyUFuncObject *ufunc,
+- NPY_CASTING casting,
+- PyArrayObject **operands,
+- PyObject *type_tup,
+- PyArray_Descr **out_dtypes)
+-{
+- int *types;
+- PyArray_Descr **dtypes;
+-
+- if (ufunc->userloops) {
+- Py_ssize_t unused_pos = 0;
+- PyObject *userloop;
+- PyUFunc_Loop1d *funcdata;
+-
+- if (ufunc->ntypes > 0 || PyDict_Size(ufunc->userloops) != 1) {
+- goto fail;
+- }
+- /* No iteration needed; only one entry in dict */
+- PyDict_Next(ufunc->userloops, &unused_pos, NULL, &userloop);
+- funcdata = (PyUFunc_Loop1d *)PyCapsule_GetPointer(userloop, NULL);
+- /* There should be only one function */
+- if (funcdata->next != NULL) {
+- goto fail;
+- }
+- types = funcdata->arg_types;
+- dtypes = funcdata->arg_dtypes;
+- }
+- else {
+- npy_intp j;
+- int types_array[NPY_MAXARGS];
+-
+- if (ufunc->ntypes != 1) {
+- goto fail;
+- }
+- /* Copy the types into an int array for matching */
+- for (j = 0; j < ufunc->nargs; ++j) {
+- types_array[j] = ufunc->types[j];
+- }
+- types = types_array;
+- dtypes = NULL;
+- }
+- switch (ufunc_loop_matches(ufunc, operands, casting, types, dtypes)) {
+- case 1: /* Matching types */
+- return set_ufunc_loop_data_types(ufunc, operands, out_dtypes,
+- types, dtypes);
+- case -1: /* Error */
+- return -1;
+- }
+- /* No match */
+- PyErr_Format(PyExc_TypeError,
+- "ufunc '%s' not supported for the input types, and the "
+- "inputs could not be safely coerced to any supported "
+- "types according to the casting rule '%s'",
+- ufunc->name, npy_casting_to_string(casting));
+- return -1;
+-
+-fail:
+- /* More than one loop or function */
+- PyErr_Format(PyExc_RuntimeError,
+- "Unexpected internal error: ufunc '%s' wraps an ERFA "
+- "function and should have only a single loop with a "
+- "single function, yet has more.",
+- ufunc->name);
+- return -1;
+-}
+-
+-/*
+- * LEAP SECOND ACCESS
+- *
+- * Getting/Setting ERFAs built-in TAI-UTC table.
+- *
+- * TODO: the whole procedure is not sub-interpreter safe.
+- * In this module, one might get dt_eraLEAPSECOND out of the module dict,
+- * and store the leap_second array in a per-module struct (see PEP 3121).
+- * But one then would also have to adapt erfa/dat.c to not use a
+- * static leap second table. Possibly best might be to copy dat.c here
+- * and put the table into the per-module struct as well.
+- */
+-static PyArray_Descr *dt_eraLEAPSECOND = NULL; /* Set in PyInit_ufunc */
+-
+-static PyObject *
+-get_leap_seconds(PyObject *NPY_UNUSED(module), PyObject *NPY_UNUSED(args)) {
+- eraLEAPSECOND *leapseconds;
+- npy_intp count;
+- PyArrayObject *array;
+- /* Get the leap seconds from ERFA */
+- count = (npy_intp)eraGetLeapSeconds(&leapseconds);
+- if (count < 0) {
+- PyErr_SetString(PyExc_RuntimeError,
+- "Unpexected failure to get ERFA leap seconds.");
+- return NULL;
+- }
+- /* Allocate an array to hold them */
+- Py_INCREF(dt_eraLEAPSECOND);
+- array = (PyArrayObject *)PyArray_NewFromDescr(
+- &PyArray_Type, dt_eraLEAPSECOND, 1, &count, NULL, NULL, 0, NULL);
+- if (array == NULL) {
+- return NULL;
+- }
+- /* Copy the leap seconds over into the array */
+- memcpy(PyArray_DATA(array), leapseconds, count*sizeof(eraLEAPSECOND));
+- return (PyObject *)array;
+-}
+-
+-static PyObject *
+-set_leap_seconds(PyObject *NPY_UNUSED(module), PyObject *args) {
+- PyObject *leap_seconds = NULL;
+- PyArrayObject *array;
+- static PyArrayObject *leap_second_array = NULL;
+-
+- if (!PyArg_ParseTuple(args, "|O:set_leap_seconds", &leap_seconds)) {
+- return NULL;
+- }
+- if (leap_seconds != NULL && leap_seconds != Py_None) {
+- /*
+- * Convert the input to an array with the proper dtype;
+- * Ensure a copy is made so one cannot change the data by changing
+- * the input array.
+- */
+- Py_INCREF(dt_eraLEAPSECOND);
+- array = (PyArrayObject *)PyArray_FromAny(leap_seconds, dt_eraLEAPSECOND,
+- 1, 1, (NPY_ARRAY_CARRAY | NPY_ARRAY_ENSURECOPY), NULL);
+- if (array == NULL) {
+- return NULL;
+- }
+- if (PyArray_SIZE(array) == 0) {
+- PyErr_SetString(PyExc_ValueError,
+- "Leap second array must have at least one entry.");
+- }
+- /*
+- * Use the array for the new leap seconds.
+- */
+- eraSetLeapSeconds(PyArray_DATA(array), PyArray_SIZE(array));
+- }
+- else {
+- /*
+- * If no input is given, reset leap second table.
+- */
+- array = NULL;
+- eraSetLeapSeconds(NULL, 0);
+- }
+- /*
+- * If we allocated a leap second array before, deallocate it,
+- * and set it to remember any allocation from PyArray_FromAny.
+- */
+- if (leap_second_array != NULL) {
+- Py_DECREF(leap_second_array);
+- }
+- leap_second_array = array;
+- Py_RETURN_NONE;
+-}
+-
+-/*
+- * UFUNC MODULE DEFINITIONS AND INITIALIZATION
+- */
+-static PyMethodDef ErfaUFuncMethods[] = {
+- {"get_leap_seconds", (PyCFunction)get_leap_seconds,
+- METH_NOARGS, GET_LEAP_SECONDS_DOCSTRING},
+- {"set_leap_seconds", (PyCFunction)set_leap_seconds,
+- METH_VARARGS, SET_LEAP_SECONDS_DOCSTRING},
+- {NULL, NULL, 0, NULL}
+-};
+-
+-static struct PyModuleDef moduledef = {
+- PyModuleDef_HEAD_INIT,
+- "ufunc",
+- MODULE_DOCSTRING,
+- -1,
+- ErfaUFuncMethods,
+- NULL,
+- NULL,
+- NULL,
+- NULL
+-};
+-
+-PyMODINIT_FUNC PyInit_ufunc(void)
+-{
+- /* module and its dict */
+- PyObject *m, *d;
+- /* structured dtypes and their definition */
+- PyObject *dtype_def;
+- PyArray_Descr *dt_double = NULL, *dt_int = NULL;
+- PyArray_Descr *dt_pv = NULL, *dt_pvdpv = NULL;
+- PyArray_Descr *dt_ymdf = NULL, *dt_hmsf = NULL, *dt_dmsf = NULL;
+- PyArray_Descr *dt_sign = NULL, *dt_type = NULL;
+- PyArray_Descr *dt_eraASTROM = NULL, *dt_eraLDBODY = NULL;
+- PyArray_Descr *dtypes[NPY_MAXARGS];
+- /* ufuncs and their definitions */
+- int status;
+- PyUFuncObject *ufunc;
+- static void *data[1] = {NULL};
+- static char types_cal2jd[6] = { NPY_INT, NPY_INT, NPY_INT, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_cal2jd[1] = { &ufunc_loop_cal2jd };
+- static char types_epb[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_epb[1] = { &ufunc_loop_epb };
+- static char types_epb2jd[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_epb2jd[1] = { &ufunc_loop_epb2jd };
+- static char types_epj[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_epj[1] = { &ufunc_loop_epj };
+- static char types_epj2jd[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_epj2jd[1] = { &ufunc_loop_epj2jd };
+- static char types_jd2cal[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_INT, NPY_INT, NPY_INT, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_jd2cal[1] = { &ufunc_loop_jd2cal };
+- static char types_ab[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ab[1] = { &ufunc_loop_ab };
+- static char types_atci13[11] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_atci13[1] = { &ufunc_loop_atci13 };
+- static char types_atco13[25] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_atco13[1] = { &ufunc_loop_atco13 };
+- static char types_atic13[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_atic13[1] = { &ufunc_loop_atic13 };
+- static char types_atio13[20] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_atio13[1] = { &ufunc_loop_atio13 };
+- static char types_ld[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ld[1] = { &ufunc_loop_ld };
+- static char types_ldsun[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ldsun[1] = { &ufunc_loop_ldsun };
+- static char types_pmpx[9] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pmpx[1] = { &ufunc_loop_pmpx };
+- static char types_pmsafe[17] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_pmsafe[1] = { &ufunc_loop_pmsafe };
+- static char types_refco[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_refco[1] = { &ufunc_loop_refco };
+- static char types_fad03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fad03[1] = { &ufunc_loop_fad03 };
+- static char types_fae03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fae03[1] = { &ufunc_loop_fae03 };
+- static char types_faf03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_faf03[1] = { &ufunc_loop_faf03 };
+- static char types_faju03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_faju03[1] = { &ufunc_loop_faju03 };
+- static char types_fal03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fal03[1] = { &ufunc_loop_fal03 };
+- static char types_falp03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_falp03[1] = { &ufunc_loop_falp03 };
+- static char types_fama03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fama03[1] = { &ufunc_loop_fama03 };
+- static char types_fame03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fame03[1] = { &ufunc_loop_fame03 };
+- static char types_fane03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fane03[1] = { &ufunc_loop_fane03 };
+- static char types_faom03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_faom03[1] = { &ufunc_loop_faom03 };
+- static char types_fapa03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fapa03[1] = { &ufunc_loop_fapa03 };
+- static char types_fasa03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fasa03[1] = { &ufunc_loop_fasa03 };
+- static char types_faur03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_faur03[1] = { &ufunc_loop_faur03 };
+- static char types_fave03[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fave03[1] = { &ufunc_loop_fave03 };
+- static char types_bi00[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_bi00[1] = { &ufunc_loop_bi00 };
+- static char types_bp00[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_bp00[1] = { &ufunc_loop_bp00 };
+- static char types_bp06[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_bp06[1] = { &ufunc_loop_bp06 };
+- static char types_bpn2xy[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_bpn2xy[1] = { &ufunc_loop_bpn2xy };
+- static char types_c2i00a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2i00a[1] = { &ufunc_loop_c2i00a };
+- static char types_c2i00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2i00b[1] = { &ufunc_loop_c2i00b };
+- static char types_c2i06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2i06a[1] = { &ufunc_loop_c2i06a };
+- static char types_c2ibpn[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2ibpn[1] = { &ufunc_loop_c2ibpn };
+- static char types_c2ixy[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2ixy[1] = { &ufunc_loop_c2ixy };
+- static char types_c2ixys[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2ixys[1] = { &ufunc_loop_c2ixys };
+- static char types_c2t00a[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2t00a[1] = { &ufunc_loop_c2t00a };
+- static char types_c2t00b[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2t00b[1] = { &ufunc_loop_c2t00b };
+- static char types_c2t06a[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2t06a[1] = { &ufunc_loop_c2t06a };
+- static char types_c2tcio[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2tcio[1] = { &ufunc_loop_c2tcio };
+- static char types_c2teqx[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2teqx[1] = { &ufunc_loop_c2teqx };
+- static char types_c2tpe[9] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2tpe[1] = { &ufunc_loop_c2tpe };
+- static char types_c2txy[9] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2txy[1] = { &ufunc_loop_c2txy };
+- static char types_eo06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eo06a[1] = { &ufunc_loop_eo06a };
+- static char types_eors[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eors[1] = { &ufunc_loop_eors };
+- static char types_fw2m[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fw2m[1] = { &ufunc_loop_fw2m };
+- static char types_fw2xy[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fw2xy[1] = { &ufunc_loop_fw2xy };
+- static char types_ltp[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ltp[1] = { &ufunc_loop_ltp };
+- static char types_ltpb[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ltpb[1] = { &ufunc_loop_ltpb };
+- static char types_ltpecl[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ltpecl[1] = { &ufunc_loop_ltpecl };
+- static char types_ltpequ[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ltpequ[1] = { &ufunc_loop_ltpequ };
+- static char types_num00a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_num00a[1] = { &ufunc_loop_num00a };
+- static char types_num00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_num00b[1] = { &ufunc_loop_num00b };
+- static char types_num06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_num06a[1] = { &ufunc_loop_num06a };
+- static char types_numat[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_numat[1] = { &ufunc_loop_numat };
+- static char types_nut00a[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_nut00a[1] = { &ufunc_loop_nut00a };
+- static char types_nut00b[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_nut00b[1] = { &ufunc_loop_nut00b };
+- static char types_nut06a[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_nut06a[1] = { &ufunc_loop_nut06a };
+- static char types_nut80[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_nut80[1] = { &ufunc_loop_nut80 };
+- static char types_nutm80[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_nutm80[1] = { &ufunc_loop_nutm80 };
+- static char types_obl06[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_obl06[1] = { &ufunc_loop_obl06 };
+- static char types_obl80[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_obl80[1] = { &ufunc_loop_obl80 };
+- static char types_p06e[18] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_p06e[1] = { &ufunc_loop_p06e };
+- static char types_pb06[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pb06[1] = { &ufunc_loop_pb06 };
+- static char types_pfw06[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pfw06[1] = { &ufunc_loop_pfw06 };
+- static char types_pmat00[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pmat00[1] = { &ufunc_loop_pmat00 };
+- static char types_pmat06[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pmat06[1] = { &ufunc_loop_pmat06 };
+- static char types_pmat76[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pmat76[1] = { &ufunc_loop_pmat76 };
+- static char types_pn00[10] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn00[1] = { &ufunc_loop_pn00 };
+- static char types_pn00a[10] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn00a[1] = { &ufunc_loop_pn00a };
+- static char types_pn00b[10] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn00b[1] = { &ufunc_loop_pn00b };
+- static char types_pn06[10] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn06[1] = { &ufunc_loop_pn06 };
+- static char types_pn06a[10] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn06a[1] = { &ufunc_loop_pn06a };
+- static char types_pnm00a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pnm00a[1] = { &ufunc_loop_pnm00a };
+- static char types_pnm00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pnm00b[1] = { &ufunc_loop_pnm00b };
+- static char types_pnm06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pnm06a[1] = { &ufunc_loop_pnm06a };
+- static char types_pnm80[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pnm80[1] = { &ufunc_loop_pnm80 };
+- static char types_pom00[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pom00[1] = { &ufunc_loop_pom00 };
+- static char types_pr00[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pr00[1] = { &ufunc_loop_pr00 };
+- static char types_prec76[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_prec76[1] = { &ufunc_loop_prec76 };
+- static char types_s00[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s00[1] = { &ufunc_loop_s00 };
+- static char types_s00a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s00a[1] = { &ufunc_loop_s00a };
+- static char types_s00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s00b[1] = { &ufunc_loop_s00b };
+- static char types_s06[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s06[1] = { &ufunc_loop_s06 };
+- static char types_s06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s06a[1] = { &ufunc_loop_s06a };
+- static char types_sp00[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_sp00[1] = { &ufunc_loop_sp00 };
+- static char types_xy06[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_xy06[1] = { &ufunc_loop_xy06 };
+- static char types_xys00a[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_xys00a[1] = { &ufunc_loop_xys00a };
+- static char types_xys00b[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_xys00b[1] = { &ufunc_loop_xys00b };
+- static char types_xys06a[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_xys06a[1] = { &ufunc_loop_xys06a };
+- static char types_ee00[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ee00[1] = { &ufunc_loop_ee00 };
+- static char types_ee00a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ee00a[1] = { &ufunc_loop_ee00a };
+- static char types_ee00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ee00b[1] = { &ufunc_loop_ee00b };
+- static char types_ee06a[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ee06a[1] = { &ufunc_loop_ee06a };
+- static char types_eect00[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eect00[1] = { &ufunc_loop_eect00 };
+- static char types_eqeq94[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eqeq94[1] = { &ufunc_loop_eqeq94 };
+- static char types_era00[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_era00[1] = { &ufunc_loop_era00 };
+- static char types_gmst00[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gmst00[1] = { &ufunc_loop_gmst00 };
+- static char types_gmst06[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gmst06[1] = { &ufunc_loop_gmst06 };
+- static char types_gmst82[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gmst82[1] = { &ufunc_loop_gmst82 };
+- static char types_gst00a[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gst00a[1] = { &ufunc_loop_gst00a };
+- static char types_gst00b[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gst00b[1] = { &ufunc_loop_gst00b };
+- static char types_gst06[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gst06[1] = { &ufunc_loop_gst06 };
+- static char types_gst06a[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gst06a[1] = { &ufunc_loop_gst06a };
+- static char types_gst94[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_gst94[1] = { &ufunc_loop_gst94 };
+- static char types_fk425[12] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk425[1] = { &ufunc_loop_fk425 };
+- static char types_fk45z[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk45z[1] = { &ufunc_loop_fk45z };
+- static char types_fk524[12] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk524[1] = { &ufunc_loop_fk524 };
+- static char types_fk52h[12] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk52h[1] = { &ufunc_loop_fk52h };
+- static char types_fk54z[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk54z[1] = { &ufunc_loop_fk54z };
+- static char types_fk5hip[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk5hip[1] = { &ufunc_loop_fk5hip };
+- static char types_fk5hz[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_fk5hz[1] = { &ufunc_loop_fk5hz };
+- static char types_h2fk5[12] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_h2fk5[1] = { &ufunc_loop_h2fk5 };
+- static char types_hfk5z[8] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_hfk5z[1] = { &ufunc_loop_hfk5z };
+- static char types_starpm[17] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_starpm[1] = { &ufunc_loop_starpm };
+- static char types_eceq06[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eceq06[1] = { &ufunc_loop_eceq06 };
+- static char types_ecm06[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ecm06[1] = { &ufunc_loop_ecm06 };
+- static char types_eqec06[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_eqec06[1] = { &ufunc_loop_eqec06 };
+- static char types_lteceq[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_lteceq[1] = { &ufunc_loop_lteceq };
+- static char types_ltecm[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ltecm[1] = { &ufunc_loop_ltecm };
+- static char types_lteqec[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_lteqec[1] = { &ufunc_loop_lteqec };
+- static char types_g2icrs[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_g2icrs[1] = { &ufunc_loop_g2icrs };
+- static char types_icrs2g[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_icrs2g[1] = { &ufunc_loop_icrs2g };
+- static char types_eform[4] = { NPY_INT, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_eform[1] = { &ufunc_loop_eform };
+- static char types_gc2gd[6] = { NPY_INT, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_gc2gd[1] = { &ufunc_loop_gc2gd };
+- static char types_gc2gde[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_gc2gde[1] = { &ufunc_loop_gc2gde };
+- static char types_gd2gc[6] = { NPY_INT, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_gd2gc[1] = { &ufunc_loop_gd2gc };
+- static char types_gd2gce[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_gd2gce[1] = { &ufunc_loop_gd2gce };
+- static char types_dat[6] = { NPY_INT, NPY_INT, NPY_INT, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_dat[1] = { &ufunc_loop_dat };
+- static char types_dtdb[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_dtdb[1] = { &ufunc_loop_dtdb };
+- static char types_taitt[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_taitt[1] = { &ufunc_loop_taitt };
+- static char types_taiut1[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_taiut1[1] = { &ufunc_loop_taiut1 };
+- static char types_taiutc[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_taiutc[1] = { &ufunc_loop_taiutc };
+- static char types_tcbtdb[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tcbtdb[1] = { &ufunc_loop_tcbtdb };
+- static char types_tcgtt[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tcgtt[1] = { &ufunc_loop_tcgtt };
+- static char types_tdbtcb[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tdbtcb[1] = { &ufunc_loop_tdbtcb };
+- static char types_tdbtt[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tdbtt[1] = { &ufunc_loop_tdbtt };
+- static char types_tttai[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tttai[1] = { &ufunc_loop_tttai };
+- static char types_tttcg[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tttcg[1] = { &ufunc_loop_tttcg };
+- static char types_tttdb[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tttdb[1] = { &ufunc_loop_tttdb };
+- static char types_ttut1[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_ttut1[1] = { &ufunc_loop_ttut1 };
+- static char types_ut1tai[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_ut1tai[1] = { &ufunc_loop_ut1tai };
+- static char types_ut1tt[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_ut1tt[1] = { &ufunc_loop_ut1tt };
+- static char types_ut1utc[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_ut1utc[1] = { &ufunc_loop_ut1utc };
+- static char types_utctai[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_utctai[1] = { &ufunc_loop_utctai };
+- static char types_utcut1[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_utcut1[1] = { &ufunc_loop_utcut1 };
+- static char types_ae2hd[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ae2hd[1] = { &ufunc_loop_ae2hd };
+- static char types_hd2ae[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_hd2ae[1] = { &ufunc_loop_hd2ae };
+- static char types_hd2pa[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_hd2pa[1] = { &ufunc_loop_hd2pa };
+- static char types_tpors[9] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tpors[1] = { &ufunc_loop_tpors };
+- static char types_tporv[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tporv[1] = { &ufunc_loop_tporv };
+- static char types_tpsts[6] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_tpsts[1] = { &ufunc_loop_tpsts };
+- static char types_tpstv[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_tpstv[1] = { &ufunc_loop_tpstv };
+- static char types_tpxes[7] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tpxes[1] = { &ufunc_loop_tpxes };
+- static char types_tpxev[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT };
+- static PyUFuncGenericFunction funcs_tpxev[1] = { &ufunc_loop_tpxev };
+- static char types_anp[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_anp[1] = { &ufunc_loop_anp };
+- static char types_anpm[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_anpm[1] = { &ufunc_loop_anpm };
+- static char types_rx[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rx[1] = { &ufunc_loop_rx };
+- static char types_ry[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ry[1] = { &ufunc_loop_ry };
+- static char types_rz[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rz[1] = { &ufunc_loop_rz };
+- static char types_cp[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_cp[1] = { &ufunc_loop_cp };
+- static char types_cr[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_cr[1] = { &ufunc_loop_cr };
+- static char types_ir[1] = { NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ir[1] = { &ufunc_loop_ir };
+- static char types_zp[1] = { NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_zp[1] = { &ufunc_loop_zp };
+- static char types_zr[1] = { NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_zr[1] = { &ufunc_loop_zr };
+- static char types_rxr[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rxr[1] = { &ufunc_loop_rxr };
+- static char types_tr[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_tr[1] = { &ufunc_loop_tr };
+- static char types_rxp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rxp[1] = { &ufunc_loop_rxp };
+- static char types_trxp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_trxp[1] = { &ufunc_loop_trxp };
+- static char types_rm2v[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rm2v[1] = { &ufunc_loop_rm2v };
+- static char types_rv2m[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_rv2m[1] = { &ufunc_loop_rv2m };
+- static char types_pap[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pap[1] = { &ufunc_loop_pap };
+- static char types_pas[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pas[1] = { &ufunc_loop_pas };
+- static char types_sepp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_sepp[1] = { &ufunc_loop_sepp };
+- static char types_seps[5] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_seps[1] = { &ufunc_loop_seps };
+- static char types_c2s[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_c2s[1] = { &ufunc_loop_c2s };
+- static char types_p2s[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_p2s[1] = { &ufunc_loop_p2s };
+- static char types_s2c[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s2c[1] = { &ufunc_loop_s2c };
+- static char types_s2p[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_s2p[1] = { &ufunc_loop_s2p };
+- static char types_pdp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pdp[1] = { &ufunc_loop_pdp };
+- static char types_pm[2] = { NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pm[1] = { &ufunc_loop_pm };
+- static char types_pmp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pmp[1] = { &ufunc_loop_pmp };
+- static char types_pn[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pn[1] = { &ufunc_loop_pn };
+- static char types_ppp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ppp[1] = { &ufunc_loop_ppp };
+- static char types_ppsp[4] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_ppsp[1] = { &ufunc_loop_ppsp };
+- static char types_pxp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_pxp[1] = { &ufunc_loop_pxp };
+- static char types_sxp[3] = { NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE };
+- static PyUFuncGenericFunction funcs_sxp[1] = { &ufunc_loop_sxp };
+-
+- m = PyModule_Create(&moduledef);
+- if (m == NULL) {
+- return NULL;
+- }
+- d = PyModule_GetDict(m); /* borrowed ref. */
+- if (d == NULL) {
+- goto fail;
+- }
+-
+- import_array();
+- import_umath();
+- /*
+- * Define the basic and structured types used in erfa so that
+- * we can use them for definitions of userloops below.
+- */
+- dt_double = PyArray_DescrFromType(NPY_DOUBLE);
+- dt_int = PyArray_DescrFromType(NPY_INT);
+- /* double[2][3] = pv */
+- dtype_def = Py_BuildValue("[(s, s), (s, s)]",
+- "p", "(3,)f8", "v", "(3,)f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_pv);
+- Py_DECREF(dtype_def);
+- /* double[2] = pvdpv */
+- dtype_def = Py_BuildValue("[(s, s), (s, s)]",
+- "pdp", "f8", "pdv", "f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_pvdpv);
+- Py_DECREF(dtype_def);
+- /* int[4] = ymdf, hmsf, dmsf */
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "y", "i4", "m", "i4", "d", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_ymdf);
+- Py_DECREF(dtype_def);
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "h", "i4", "m", "i4", "s", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_hmsf);
+- Py_DECREF(dtype_def);
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s), (s, s)]",
+- "h", "i4", "m", "i4", "s", "i4", "f", "i4");
+- PyArray_DescrAlignConverter(dtype_def, &dt_dmsf);
+- Py_DECREF(dtype_def);
+- /* char1 (have to use structured, otherwise it cannot be a user type) */
+- dtype_def = Py_BuildValue("[(s, s)]", "sign", "S1");
+- PyArray_DescrAlignConverter(dtype_def, &dt_sign);
+- Py_DECREF(dtype_def);
+- /* char12 */
+- dtype_def = Py_BuildValue("[(s, s)]", "type", "S12");
+- PyArray_DescrAlignConverter(dtype_def, &dt_type);
+- Py_DECREF(dtype_def);
+- /* eraLDBODY */
+- dtype_def = Py_BuildValue(
+- "[(s, s), (s, s), (s, s)]",
+- "bm", "f8", /* mass of the body (solar masses) */
+- "dl", "f8", /* deflection limiter (radians^2/2) */
+- "pv", "(2,3)f8" /* barycentric PV of the body (au, au/day) */
+- );
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraLDBODY);
+- Py_DECREF(dtype_def);
+- /* eraASTROM */
+- dtype_def = Py_BuildValue(
+- "[(s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s),"
+- " (s, s), (s, s), (s, s), (s, s), (s, s)]",
+- "pmt", "f8", /* PM time interval (SSB, Julian years) */
+- "eb", "(3,)f8", /* SSB to observer (vector, au) */
+- "eh", "(3,)f8", /* Sun to observer (unit vector) */
+- "em", "f8", /* distance from Sun to observer (au) */
+- "v", "(3,)f8", /* barycentric observer velocity (vector, c) */
+- "bm1", "f8", /* sqrt(1-|v|^2): reciprocal of Lorenz factor */
+- "bpn", "(3,3)f8", /* bias-precession-nutation matrix */
+- "along", "f8", /* longitude + s' + dERA(DUT) (radians) */
+- "phi", "f8", /* geodetic latitude (radians) */
+- "xpl", "f8", /* polar motion xp wrt local meridian (radians) */
+- "ypl", "f8", /* polar motion yp wrt local meridian (radians) */
+- "sphi", "f8", /* sine of geodetic latitude */
+- "cphi", "f8", /* cosine of geodetic latitude */
+- "diurab", "f8", /* magnitude of diurnal aberration vector */
+- "eral", "f8", /* "local" Earth rotation angle (radians) */
+- "refa", "f8", /* refraction constant A (radians) */
+- "refb", "f8" /* refraction constant B (radians) */
+- );
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraASTROM);
+- Py_DECREF(dtype_def);
+- /* eraLEAPSECOND */
+- dtype_def = Py_BuildValue("[(s, s), (s, s), (s, s)]",
+- "year", "i4", "month", "i4", "tai_utc", "f8");
+- PyArray_DescrAlignConverter(dtype_def, &dt_eraLEAPSECOND);
+- Py_DECREF(dtype_def);
+-
+- if (dt_double == NULL || dt_int == NULL ||
+- dt_pv == NULL || dt_pvdpv == NULL ||
+- dt_ymdf == NULL || dt_hmsf == NULL || dt_dmsf == NULL ||
+- dt_sign == NULL || dt_type == NULL ||
+- dt_eraLDBODY == NULL || dt_eraASTROM == NULL ||
+- dt_eraLEAPSECOND == NULL) {
+- goto fail;
+- }
+- /* Make the structured dtypes available in the module */
+- PyDict_SetItemString(d, "dt_pv", (PyObject *)dt_pv);
+- PyDict_SetItemString(d, "dt_pvdpv", (PyObject *)dt_pvdpv);
+- PyDict_SetItemString(d, "dt_ymdf", (PyObject *)dt_ymdf);
+- PyDict_SetItemString(d, "dt_hmsf", (PyObject *)dt_hmsf);
+- PyDict_SetItemString(d, "dt_dmsf", (PyObject *)dt_dmsf);
+- PyDict_SetItemString(d, "dt_sign", (PyObject *)dt_sign);
+- PyDict_SetItemString(d, "dt_type", (PyObject *)dt_type);
+- PyDict_SetItemString(d, "dt_eraLDBODY", (PyObject *)dt_eraLDBODY);
+- PyDict_SetItemString(d, "dt_eraASTROM", (PyObject *)dt_eraASTROM);
+- PyDict_SetItemString(d, "dt_eraLEAPSECOND", (PyObject *)dt_eraLEAPSECOND);
+- /*
+- * Define the ufuncs. For those without structured dtypes,
+- * the ufunc creation uses the static variables defined above;
+- * for those with structured dtypes, an empty ufunc is created,
+- * and then a userloop is added. For both, we set the type
+- * resolver to our own, and then add the ufunc to the module.
+- *
+- * Note that for the arguments, any inout arguments, i.e., those
+- * that are changed in-place in the ERFA function, are repeated,
+- * since we want the ufuncs not to do in-place changes (unless
+- * explicitly requested with ufunc(..., in,..., out=in))
+- */
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_cal2jd, data, types_cal2jd,
+- 1, 3, 3, PyUFunc_None,
+- "cal2jd",
+- "UFunc wrapper for eraCal2jd",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "cal2jd", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_epb, data, types_epb,
+- 1, 2, 1, PyUFunc_None,
+- "epb",
+- "UFunc wrapper for eraEpb",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "epb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_epb2jd, data, types_epb2jd,
+- 1, 1, 2, PyUFunc_None,
+- "epb2jd",
+- "UFunc wrapper for eraEpb2jd",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "epb2jd", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_epj, data, types_epj,
+- 1, 2, 1, PyUFunc_None,
+- "epj",
+- "UFunc wrapper for eraEpj",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "epj", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_epj2jd, data, types_epj2jd,
+- 1, 1, 2, PyUFunc_None,
+- "epj2jd",
+- "UFunc wrapper for eraEpj2jd",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "epj2jd", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_jd2cal, data, types_jd2cal,
+- 1, 2, 5, PyUFunc_None,
+- "jd2cal",
+- "UFunc wrapper for eraJd2cal",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "jd2cal", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 2, PyUFunc_None,
+- "jdcalf",
+- "UFunc wrapper for eraJdcalf",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_int;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_ymdf;
+- dtypes[4] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_ymdf,
+- ufunc_loop_jdcalf, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "jdcalf", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ab, data, types_ab,
+- 1, 4, 1, PyUFunc_None,
+- "ab",
+- "UFunc wrapper for eraAb",
+- 0, "(3),(3),(),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ab", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 1, PyUFunc_None,
+- "apcg",
+- "UFunc wrapper for eraApcg",
+- 0, "(),(),(),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_apcg, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apcg", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "apcg13",
+- "UFunc wrapper for eraApcg13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_apcg13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apcg13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 7, 1, PyUFunc_None,
+- "apci",
+- "UFunc wrapper for eraApci",
+- 0, "(),(),(),(3),(),(),()->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_apci, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apci", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 2, PyUFunc_None,
+- "apci13",
+- "UFunc wrapper for eraApci13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_apci13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apci13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 16, 1, PyUFunc_None,
+- "apco",
+- "UFunc wrapper for eraApco",
+- 0, "(),(),(),(3),(),(),(),(),(),(),(),(),(),(),(),()->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- dtypes[10] = dt_double;
+- dtypes[11] = dt_double;
+- dtypes[12] = dt_double;
+- dtypes[13] = dt_double;
+- dtypes[14] = dt_double;
+- dtypes[15] = dt_double;
+- dtypes[16] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_apco, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apco", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 12, 3, PyUFunc_None,
+- "apco13",
+- "UFunc wrapper for eraApco13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- dtypes[10] = dt_double;
+- dtypes[11] = dt_double;
+- dtypes[12] = dt_eraASTROM;
+- dtypes[13] = dt_double;
+- dtypes[14] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_apco13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apco13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 5, 1, PyUFunc_None,
+- "apcs",
+- "UFunc wrapper for eraApcs",
+- 0, "(),(),(),(),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_pv;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_apcs, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apcs", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 1, PyUFunc_None,
+- "apcs13",
+- "UFunc wrapper for eraApcs13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_apcs13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apcs13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "aper",
+- "UFunc wrapper for eraAper",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_eraASTROM;
+- dtypes[2] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_aper, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "aper", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 1, PyUFunc_None,
+- "aper13",
+- "UFunc wrapper for eraAper13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_aper13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "aper13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 9, 1, PyUFunc_None,
+- "apio",
+- "UFunc wrapper for eraApio",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_eraASTROM;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_apio, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apio", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 12, 2, PyUFunc_None,
+- "apio13",
+- "UFunc wrapper for eraApio13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- dtypes[10] = dt_double;
+- dtypes[11] = dt_double;
+- dtypes[12] = dt_eraASTROM;
+- dtypes[13] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_apio13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "apio13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_atci13, data, types_atci13,
+- 1, 8, 3, PyUFunc_None,
+- "atci13",
+- "UFunc wrapper for eraAtci13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atci13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 7, 2, PyUFunc_None,
+- "atciq",
+- "UFunc wrapper for eraAtciq",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_eraASTROM;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_atciq, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atciq", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 8, 2, PyUFunc_None,
+- "atciqn",
+- "UFunc wrapper for eraAtciqn",
+- 0, "(),(),(),(),(),(),(),(n)->(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_eraASTROM;
+- dtypes[7] = dt_eraLDBODY;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraLDBODY,
+- ufunc_loop_atciqn, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atciqn", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 2, PyUFunc_None,
+- "atciqz",
+- "UFunc wrapper for eraAtciqz",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_atciqz, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atciqz", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_atco13, data, types_atco13,
+- 1, 18, 7, PyUFunc_None,
+- "atco13",
+- "UFunc wrapper for eraAtco13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atco13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_atic13, data, types_atic13,
+- 1, 4, 3, PyUFunc_None,
+- "atic13",
+- "UFunc wrapper for eraAtic13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atic13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 2, PyUFunc_None,
+- "aticq",
+- "UFunc wrapper for eraAticq",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_aticq, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "aticq", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 2, PyUFunc_None,
+- "aticqn",
+- "UFunc wrapper for eraAticqn",
+- 0, "(),(),(),(n)->(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_eraLDBODY;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraLDBODY,
+- ufunc_loop_aticqn, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "aticqn", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_atio13, data, types_atio13,
+- 1, 14, 6, PyUFunc_None,
+- "atio13",
+- "UFunc wrapper for eraAtio13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atio13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 5, PyUFunc_None,
+- "atioq",
+- "UFunc wrapper for eraAtioq",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_eraASTROM;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraASTROM,
+- ufunc_loop_atioq, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atioq", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 15, 3, PyUFunc_None,
+- "atoc13",
+- "UFunc wrapper for eraAtoc13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_type;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- dtypes[10] = dt_double;
+- dtypes[11] = dt_double;
+- dtypes[12] = dt_double;
+- dtypes[13] = dt_double;
+- dtypes[14] = dt_double;
+- dtypes[15] = dt_double;
+- dtypes[16] = dt_double;
+- dtypes[17] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_type,
+- ufunc_loop_atoc13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atoc13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 15, 3, PyUFunc_None,
+- "atoi13",
+- "UFunc wrapper for eraAtoi13",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_type;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_double;
+- dtypes[10] = dt_double;
+- dtypes[11] = dt_double;
+- dtypes[12] = dt_double;
+- dtypes[13] = dt_double;
+- dtypes[14] = dt_double;
+- dtypes[15] = dt_double;
+- dtypes[16] = dt_double;
+- dtypes[17] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_type,
+- ufunc_loop_atoi13, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atoi13", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 2, PyUFunc_None,
+- "atoiq",
+- "UFunc wrapper for eraAtoiq",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_type;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_eraASTROM;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_type,
+- ufunc_loop_atoiq, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "atoiq", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ld, data, types_ld,
+- 1, 6, 1, PyUFunc_None,
+- "ld",
+- "UFunc wrapper for eraLd",
+- 0, "(),(3),(3),(3),(),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ld", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 1, PyUFunc_None,
+- "ldn",
+- "UFunc wrapper for eraLdn",
+- 0, "(n),(3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_eraLDBODY;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_eraLDBODY,
+- ufunc_loop_ldn, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ldn", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ldsun, data, types_ldsun,
+- 1, 3, 1, PyUFunc_None,
+- "ldsun",
+- "UFunc wrapper for eraLdsun",
+- 0, "(3),(3),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ldsun", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmpx, data, types_pmpx,
+- 1, 8, 1, PyUFunc_None,
+- "pmpx",
+- "UFunc wrapper for eraPmpx",
+- 0, "(),(),(),(),(),(),(),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmpx", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmsafe, data, types_pmsafe,
+- 1, 10, 7, PyUFunc_None,
+- "pmsafe",
+- "UFunc wrapper for eraPmsafe",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmsafe", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 7, 1, PyUFunc_None,
+- "pvtob",
+- "UFunc wrapper for eraPvtob",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvtob, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvtob", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_refco, data, types_refco,
+- 1, 4, 2, PyUFunc_None,
+- "refco",
+- "UFunc wrapper for eraRefco",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "refco", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 3, PyUFunc_None,
+- "epv00",
+- "UFunc wrapper for eraEpv00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_pv;
+- dtypes[4] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_epv00, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "epv00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 2, PyUFunc_None,
+- "plan94",
+- "UFunc wrapper for eraPlan94",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_int;
+- dtypes[3] = dt_pv;
+- dtypes[4] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_plan94, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "plan94", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fad03, data, types_fad03,
+- 1, 1, 1, PyUFunc_None,
+- "fad03",
+- "UFunc wrapper for eraFad03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fad03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fae03, data, types_fae03,
+- 1, 1, 1, PyUFunc_None,
+- "fae03",
+- "UFunc wrapper for eraFae03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fae03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_faf03, data, types_faf03,
+- 1, 1, 1, PyUFunc_None,
+- "faf03",
+- "UFunc wrapper for eraFaf03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "faf03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_faju03, data, types_faju03,
+- 1, 1, 1, PyUFunc_None,
+- "faju03",
+- "UFunc wrapper for eraFaju03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "faju03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fal03, data, types_fal03,
+- 1, 1, 1, PyUFunc_None,
+- "fal03",
+- "UFunc wrapper for eraFal03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fal03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_falp03, data, types_falp03,
+- 1, 1, 1, PyUFunc_None,
+- "falp03",
+- "UFunc wrapper for eraFalp03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "falp03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fama03, data, types_fama03,
+- 1, 1, 1, PyUFunc_None,
+- "fama03",
+- "UFunc wrapper for eraFama03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fama03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fame03, data, types_fame03,
+- 1, 1, 1, PyUFunc_None,
+- "fame03",
+- "UFunc wrapper for eraFame03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fame03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fane03, data, types_fane03,
+- 1, 1, 1, PyUFunc_None,
+- "fane03",
+- "UFunc wrapper for eraFane03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fane03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_faom03, data, types_faom03,
+- 1, 1, 1, PyUFunc_None,
+- "faom03",
+- "UFunc wrapper for eraFaom03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "faom03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fapa03, data, types_fapa03,
+- 1, 1, 1, PyUFunc_None,
+- "fapa03",
+- "UFunc wrapper for eraFapa03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fapa03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fasa03, data, types_fasa03,
+- 1, 1, 1, PyUFunc_None,
+- "fasa03",
+- "UFunc wrapper for eraFasa03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fasa03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_faur03, data, types_faur03,
+- 1, 1, 1, PyUFunc_None,
+- "faur03",
+- "UFunc wrapper for eraFaur03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "faur03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fave03, data, types_fave03,
+- 1, 1, 1, PyUFunc_None,
+- "fave03",
+- "UFunc wrapper for eraFave03",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fave03", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_bi00, data, types_bi00,
+- 1, 0, 3, PyUFunc_None,
+- "bi00",
+- "UFunc wrapper for eraBi00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "bi00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_bp00, data, types_bp00,
+- 1, 2, 3, PyUFunc_None,
+- "bp00",
+- "UFunc wrapper for eraBp00",
+- 0, "(),()->(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "bp00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_bp06, data, types_bp06,
+- 1, 2, 3, PyUFunc_None,
+- "bp06",
+- "UFunc wrapper for eraBp06",
+- 0, "(),()->(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "bp06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_bpn2xy, data, types_bpn2xy,
+- 1, 1, 2, PyUFunc_None,
+- "bpn2xy",
+- "UFunc wrapper for eraBpn2xy",
+- 0, "(3, 3)->(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "bpn2xy", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2i00a, data, types_c2i00a,
+- 1, 2, 1, PyUFunc_None,
+- "c2i00a",
+- "UFunc wrapper for eraC2i00a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2i00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2i00b, data, types_c2i00b,
+- 1, 2, 1, PyUFunc_None,
+- "c2i00b",
+- "UFunc wrapper for eraC2i00b",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2i00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2i06a, data, types_c2i06a,
+- 1, 2, 1, PyUFunc_None,
+- "c2i06a",
+- "UFunc wrapper for eraC2i06a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2i06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2ibpn, data, types_c2ibpn,
+- 1, 3, 1, PyUFunc_None,
+- "c2ibpn",
+- "UFunc wrapper for eraC2ibpn",
+- 0, "(),(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2ibpn", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2ixy, data, types_c2ixy,
+- 1, 4, 1, PyUFunc_None,
+- "c2ixy",
+- "UFunc wrapper for eraC2ixy",
+- 0, "(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2ixy", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2ixys, data, types_c2ixys,
+- 1, 3, 1, PyUFunc_None,
+- "c2ixys",
+- "UFunc wrapper for eraC2ixys",
+- 0, "(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2ixys", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2t00a, data, types_c2t00a,
+- 1, 6, 1, PyUFunc_None,
+- "c2t00a",
+- "UFunc wrapper for eraC2t00a",
+- 0, "(),(),(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2t00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2t00b, data, types_c2t00b,
+- 1, 6, 1, PyUFunc_None,
+- "c2t00b",
+- "UFunc wrapper for eraC2t00b",
+- 0, "(),(),(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2t00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2t06a, data, types_c2t06a,
+- 1, 6, 1, PyUFunc_None,
+- "c2t06a",
+- "UFunc wrapper for eraC2t06a",
+- 0, "(),(),(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2t06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2tcio, data, types_c2tcio,
+- 1, 3, 1, PyUFunc_None,
+- "c2tcio",
+- "UFunc wrapper for eraC2tcio",
+- 0, "(3, 3),(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2tcio", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2teqx, data, types_c2teqx,
+- 1, 3, 1, PyUFunc_None,
+- "c2teqx",
+- "UFunc wrapper for eraC2teqx",
+- 0, "(3, 3),(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2teqx", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2tpe, data, types_c2tpe,
+- 1, 8, 1, PyUFunc_None,
+- "c2tpe",
+- "UFunc wrapper for eraC2tpe",
+- 0, "(),(),(),(),(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2tpe", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2txy, data, types_c2txy,
+- 1, 8, 1, PyUFunc_None,
+- "c2txy",
+- "UFunc wrapper for eraC2txy",
+- 0, "(),(),(),(),(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2txy", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eo06a, data, types_eo06a,
+- 1, 2, 1, PyUFunc_None,
+- "eo06a",
+- "UFunc wrapper for eraEo06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eo06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eors, data, types_eors,
+- 1, 2, 1, PyUFunc_None,
+- "eors",
+- "UFunc wrapper for eraEors",
+- 0, "(3, 3),()->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eors", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fw2m, data, types_fw2m,
+- 1, 4, 1, PyUFunc_None,
+- "fw2m",
+- "UFunc wrapper for eraFw2m",
+- 0, "(),(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fw2m", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fw2xy, data, types_fw2xy,
+- 1, 4, 2, PyUFunc_None,
+- "fw2xy",
+- "UFunc wrapper for eraFw2xy",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fw2xy", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ltp, data, types_ltp,
+- 1, 1, 1, PyUFunc_None,
+- "ltp",
+- "UFunc wrapper for eraLtp",
+- 0, "()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ltp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ltpb, data, types_ltpb,
+- 1, 1, 1, PyUFunc_None,
+- "ltpb",
+- "UFunc wrapper for eraLtpb",
+- 0, "()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ltpb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ltpecl, data, types_ltpecl,
+- 1, 1, 1, PyUFunc_None,
+- "ltpecl",
+- "UFunc wrapper for eraLtpecl",
+- 0, "()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ltpecl", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ltpequ, data, types_ltpequ,
+- 1, 1, 1, PyUFunc_None,
+- "ltpequ",
+- "UFunc wrapper for eraLtpequ",
+- 0, "()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ltpequ", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_num00a, data, types_num00a,
+- 1, 2, 1, PyUFunc_None,
+- "num00a",
+- "UFunc wrapper for eraNum00a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "num00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_num00b, data, types_num00b,
+- 1, 2, 1, PyUFunc_None,
+- "num00b",
+- "UFunc wrapper for eraNum00b",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "num00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_num06a, data, types_num06a,
+- 1, 2, 1, PyUFunc_None,
+- "num06a",
+- "UFunc wrapper for eraNum06a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "num06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_numat, data, types_numat,
+- 1, 3, 1, PyUFunc_None,
+- "numat",
+- "UFunc wrapper for eraNumat",
+- 0, "(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "numat", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_nut00a, data, types_nut00a,
+- 1, 2, 2, PyUFunc_None,
+- "nut00a",
+- "UFunc wrapper for eraNut00a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "nut00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_nut00b, data, types_nut00b,
+- 1, 2, 2, PyUFunc_None,
+- "nut00b",
+- "UFunc wrapper for eraNut00b",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "nut00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_nut06a, data, types_nut06a,
+- 1, 2, 2, PyUFunc_None,
+- "nut06a",
+- "UFunc wrapper for eraNut06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "nut06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_nut80, data, types_nut80,
+- 1, 2, 2, PyUFunc_None,
+- "nut80",
+- "UFunc wrapper for eraNut80",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "nut80", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_nutm80, data, types_nutm80,
+- 1, 2, 1, PyUFunc_None,
+- "nutm80",
+- "UFunc wrapper for eraNutm80",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "nutm80", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_obl06, data, types_obl06,
+- 1, 2, 1, PyUFunc_None,
+- "obl06",
+- "UFunc wrapper for eraObl06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "obl06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_obl80, data, types_obl80,
+- 1, 2, 1, PyUFunc_None,
+- "obl80",
+- "UFunc wrapper for eraObl80",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "obl80", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_p06e, data, types_p06e,
+- 1, 2, 16, PyUFunc_None,
+- "p06e",
+- "UFunc wrapper for eraP06e",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "p06e", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pb06, data, types_pb06,
+- 1, 2, 3, PyUFunc_None,
+- "pb06",
+- "UFunc wrapper for eraPb06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pb06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pfw06, data, types_pfw06,
+- 1, 2, 4, PyUFunc_None,
+- "pfw06",
+- "UFunc wrapper for eraPfw06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pfw06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmat00, data, types_pmat00,
+- 1, 2, 1, PyUFunc_None,
+- "pmat00",
+- "UFunc wrapper for eraPmat00",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmat00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmat06, data, types_pmat06,
+- 1, 2, 1, PyUFunc_None,
+- "pmat06",
+- "UFunc wrapper for eraPmat06",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmat06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmat76, data, types_pmat76,
+- 1, 2, 1, PyUFunc_None,
+- "pmat76",
+- "UFunc wrapper for eraPmat76",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmat76", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn00, data, types_pn00,
+- 1, 4, 6, PyUFunc_None,
+- "pn00",
+- "UFunc wrapper for eraPn00",
+- 0, "(),(),(),()->(),(3, 3),(3, 3),(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn00a, data, types_pn00a,
+- 1, 2, 8, PyUFunc_None,
+- "pn00a",
+- "UFunc wrapper for eraPn00a",
+- 0, "(),()->(),(),(),(3, 3),(3, 3),(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn00b, data, types_pn00b,
+- 1, 2, 8, PyUFunc_None,
+- "pn00b",
+- "UFunc wrapper for eraPn00b",
+- 0, "(),()->(),(),(),(3, 3),(3, 3),(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn06, data, types_pn06,
+- 1, 4, 6, PyUFunc_None,
+- "pn06",
+- "UFunc wrapper for eraPn06",
+- 0, "(),(),(),()->(),(3, 3),(3, 3),(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn06a, data, types_pn06a,
+- 1, 2, 8, PyUFunc_None,
+- "pn06a",
+- "UFunc wrapper for eraPn06a",
+- 0, "(),()->(),(),(),(3, 3),(3, 3),(3, 3),(3, 3),(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pnm00a, data, types_pnm00a,
+- 1, 2, 1, PyUFunc_None,
+- "pnm00a",
+- "UFunc wrapper for eraPnm00a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pnm00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pnm00b, data, types_pnm00b,
+- 1, 2, 1, PyUFunc_None,
+- "pnm00b",
+- "UFunc wrapper for eraPnm00b",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pnm00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pnm06a, data, types_pnm06a,
+- 1, 2, 1, PyUFunc_None,
+- "pnm06a",
+- "UFunc wrapper for eraPnm06a",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pnm06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pnm80, data, types_pnm80,
+- 1, 2, 1, PyUFunc_None,
+- "pnm80",
+- "UFunc wrapper for eraPnm80",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pnm80", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pom00, data, types_pom00,
+- 1, 3, 1, PyUFunc_None,
+- "pom00",
+- "UFunc wrapper for eraPom00",
+- 0, "(),(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pom00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pr00, data, types_pr00,
+- 1, 2, 2, PyUFunc_None,
+- "pr00",
+- "UFunc wrapper for eraPr00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pr00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_prec76, data, types_prec76,
+- 1, 4, 3, PyUFunc_None,
+- "prec76",
+- "UFunc wrapper for eraPrec76",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "prec76", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s00, data, types_s00,
+- 1, 4, 1, PyUFunc_None,
+- "s00",
+- "UFunc wrapper for eraS00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s00a, data, types_s00a,
+- 1, 2, 1, PyUFunc_None,
+- "s00a",
+- "UFunc wrapper for eraS00a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s00b, data, types_s00b,
+- 1, 2, 1, PyUFunc_None,
+- "s00b",
+- "UFunc wrapper for eraS00b",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s06, data, types_s06,
+- 1, 4, 1, PyUFunc_None,
+- "s06",
+- "UFunc wrapper for eraS06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s06a, data, types_s06a,
+- 1, 2, 1, PyUFunc_None,
+- "s06a",
+- "UFunc wrapper for eraS06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_sp00, data, types_sp00,
+- 1, 2, 1, PyUFunc_None,
+- "sp00",
+- "UFunc wrapper for eraSp00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "sp00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_xy06, data, types_xy06,
+- 1, 2, 2, PyUFunc_None,
+- "xy06",
+- "UFunc wrapper for eraXy06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "xy06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_xys00a, data, types_xys00a,
+- 1, 2, 3, PyUFunc_None,
+- "xys00a",
+- "UFunc wrapper for eraXys00a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "xys00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_xys00b, data, types_xys00b,
+- 1, 2, 3, PyUFunc_None,
+- "xys00b",
+- "UFunc wrapper for eraXys00b",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "xys00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_xys06a, data, types_xys06a,
+- 1, 2, 3, PyUFunc_None,
+- "xys06a",
+- "UFunc wrapper for eraXys06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "xys06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ee00, data, types_ee00,
+- 1, 4, 1, PyUFunc_None,
+- "ee00",
+- "UFunc wrapper for eraEe00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ee00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ee00a, data, types_ee00a,
+- 1, 2, 1, PyUFunc_None,
+- "ee00a",
+- "UFunc wrapper for eraEe00a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ee00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ee00b, data, types_ee00b,
+- 1, 2, 1, PyUFunc_None,
+- "ee00b",
+- "UFunc wrapper for eraEe00b",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ee00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ee06a, data, types_ee06a,
+- 1, 2, 1, PyUFunc_None,
+- "ee06a",
+- "UFunc wrapper for eraEe06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ee06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eect00, data, types_eect00,
+- 1, 2, 1, PyUFunc_None,
+- "eect00",
+- "UFunc wrapper for eraEect00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eect00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eqeq94, data, types_eqeq94,
+- 1, 2, 1, PyUFunc_None,
+- "eqeq94",
+- "UFunc wrapper for eraEqeq94",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eqeq94", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_era00, data, types_era00,
+- 1, 2, 1, PyUFunc_None,
+- "era00",
+- "UFunc wrapper for eraEra00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "era00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gmst00, data, types_gmst00,
+- 1, 4, 1, PyUFunc_None,
+- "gmst00",
+- "UFunc wrapper for eraGmst00",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gmst00", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gmst06, data, types_gmst06,
+- 1, 4, 1, PyUFunc_None,
+- "gmst06",
+- "UFunc wrapper for eraGmst06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gmst06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gmst82, data, types_gmst82,
+- 1, 2, 1, PyUFunc_None,
+- "gmst82",
+- "UFunc wrapper for eraGmst82",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gmst82", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gst00a, data, types_gst00a,
+- 1, 4, 1, PyUFunc_None,
+- "gst00a",
+- "UFunc wrapper for eraGst00a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gst00a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gst00b, data, types_gst00b,
+- 1, 2, 1, PyUFunc_None,
+- "gst00b",
+- "UFunc wrapper for eraGst00b",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gst00b", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gst06, data, types_gst06,
+- 1, 5, 1, PyUFunc_None,
+- "gst06",
+- "UFunc wrapper for eraGst06",
+- 0, "(),(),(),(),(3, 3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gst06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gst06a, data, types_gst06a,
+- 1, 4, 1, PyUFunc_None,
+- "gst06a",
+- "UFunc wrapper for eraGst06a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gst06a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gst94, data, types_gst94,
+- 1, 2, 1, PyUFunc_None,
+- "gst94",
+- "UFunc wrapper for eraGst94",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gst94", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 7, PyUFunc_None,
+- "pvstar",
+- "UFunc wrapper for eraPvstar",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvstar, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvstar", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 6, 2, PyUFunc_None,
+- "starpv",
+- "UFunc wrapper for eraStarpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_pv;
+- dtypes[7] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_starpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "starpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk425, data, types_fk425,
+- 1, 6, 6, PyUFunc_None,
+- "fk425",
+- "UFunc wrapper for eraFk425",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk425", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk45z, data, types_fk45z,
+- 1, 3, 2, PyUFunc_None,
+- "fk45z",
+- "UFunc wrapper for eraFk45z",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk45z", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk524, data, types_fk524,
+- 1, 6, 6, PyUFunc_None,
+- "fk524",
+- "UFunc wrapper for eraFk524",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk524", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk52h, data, types_fk52h,
+- 1, 6, 6, PyUFunc_None,
+- "fk52h",
+- "UFunc wrapper for eraFk52h",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk52h", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk54z, data, types_fk54z,
+- 1, 3, 4, PyUFunc_None,
+- "fk54z",
+- "UFunc wrapper for eraFk54z",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk54z", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk5hip, data, types_fk5hip,
+- 1, 0, 2, PyUFunc_None,
+- "fk5hip",
+- "UFunc wrapper for eraFk5hip",
+- 0, "->(3, 3),(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk5hip", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_fk5hz, data, types_fk5hz,
+- 1, 4, 2, PyUFunc_None,
+- "fk5hz",
+- "UFunc wrapper for eraFk5hz",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "fk5hz", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_h2fk5, data, types_h2fk5,
+- 1, 6, 6, PyUFunc_None,
+- "h2fk5",
+- "UFunc wrapper for eraH2fk5",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "h2fk5", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_hfk5z, data, types_hfk5z,
+- 1, 4, 4, PyUFunc_None,
+- "hfk5z",
+- "UFunc wrapper for eraHfk5z",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "hfk5z", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_starpm, data, types_starpm,
+- 1, 10, 7, PyUFunc_None,
+- "starpm",
+- "UFunc wrapper for eraStarpm",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "starpm", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eceq06, data, types_eceq06,
+- 1, 4, 2, PyUFunc_None,
+- "eceq06",
+- "UFunc wrapper for eraEceq06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eceq06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ecm06, data, types_ecm06,
+- 1, 2, 1, PyUFunc_None,
+- "ecm06",
+- "UFunc wrapper for eraEcm06",
+- 0, "(),()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ecm06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eqec06, data, types_eqec06,
+- 1, 4, 2, PyUFunc_None,
+- "eqec06",
+- "UFunc wrapper for eraEqec06",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eqec06", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_lteceq, data, types_lteceq,
+- 1, 3, 2, PyUFunc_None,
+- "lteceq",
+- "UFunc wrapper for eraLteceq",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "lteceq", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ltecm, data, types_ltecm,
+- 1, 1, 1, PyUFunc_None,
+- "ltecm",
+- "UFunc wrapper for eraLtecm",
+- 0, "()->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ltecm", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_lteqec, data, types_lteqec,
+- 1, 3, 2, PyUFunc_None,
+- "lteqec",
+- "UFunc wrapper for eraLteqec",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "lteqec", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_g2icrs, data, types_g2icrs,
+- 1, 2, 2, PyUFunc_None,
+- "g2icrs",
+- "UFunc wrapper for eraG2icrs",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "g2icrs", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_icrs2g, data, types_icrs2g,
+- 1, 2, 2, PyUFunc_None,
+- "icrs2g",
+- "UFunc wrapper for eraIcrs2g",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "icrs2g", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_eform, data, types_eform,
+- 1, 1, 3, PyUFunc_None,
+- "eform",
+- "UFunc wrapper for eraEform",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "eform", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gc2gd, data, types_gc2gd,
+- 1, 2, 4, PyUFunc_None,
+- "gc2gd",
+- "UFunc wrapper for eraGc2gd",
+- 0, "(),(3)->(),(),(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gc2gd", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gc2gde, data, types_gc2gde,
+- 1, 3, 4, PyUFunc_None,
+- "gc2gde",
+- "UFunc wrapper for eraGc2gde",
+- 0, "(),(),(3)->(),(),(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gc2gde", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gd2gc, data, types_gd2gc,
+- 1, 4, 2, PyUFunc_None,
+- "gd2gc",
+- "UFunc wrapper for eraGd2gc",
+- 0, "(),(),(),()->(3),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gd2gc", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_gd2gce, data, types_gd2gce,
+- 1, 5, 2, PyUFunc_None,
+- "gd2gce",
+- "UFunc wrapper for eraGd2gce",
+- 0, "(),(),(),(),()->(3),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "gd2gce", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 5, PyUFunc_None,
+- "d2dtf",
+- "UFunc wrapper for eraD2dtf",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_type;
+- dtypes[1] = dt_int;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_int;
+- dtypes[5] = dt_int;
+- dtypes[6] = dt_int;
+- dtypes[7] = dt_hmsf;
+- dtypes[8] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_type,
+- ufunc_loop_d2dtf, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "d2dtf", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_dat, data, types_dat,
+- 1, 4, 2, PyUFunc_None,
+- "dat",
+- "UFunc wrapper for eraDat",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "dat", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_dtdb, data, types_dtdb,
+- 1, 6, 1, PyUFunc_None,
+- "dtdb",
+- "UFunc wrapper for eraDtdb",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "dtdb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 7, 3, PyUFunc_None,
+- "dtf2d",
+- "UFunc wrapper for eraDtf2d",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_type;
+- dtypes[1] = dt_int;
+- dtypes[2] = dt_int;
+- dtypes[3] = dt_int;
+- dtypes[4] = dt_int;
+- dtypes[5] = dt_int;
+- dtypes[6] = dt_double;
+- dtypes[7] = dt_double;
+- dtypes[8] = dt_double;
+- dtypes[9] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_type,
+- ufunc_loop_dtf2d, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "dtf2d", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_taitt, data, types_taitt,
+- 1, 2, 3, PyUFunc_None,
+- "taitt",
+- "UFunc wrapper for eraTaitt",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "taitt", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_taiut1, data, types_taiut1,
+- 1, 3, 3, PyUFunc_None,
+- "taiut1",
+- "UFunc wrapper for eraTaiut1",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "taiut1", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_taiutc, data, types_taiutc,
+- 1, 2, 3, PyUFunc_None,
+- "taiutc",
+- "UFunc wrapper for eraTaiutc",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "taiutc", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tcbtdb, data, types_tcbtdb,
+- 1, 2, 3, PyUFunc_None,
+- "tcbtdb",
+- "UFunc wrapper for eraTcbtdb",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tcbtdb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tcgtt, data, types_tcgtt,
+- 1, 2, 3, PyUFunc_None,
+- "tcgtt",
+- "UFunc wrapper for eraTcgtt",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tcgtt", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tdbtcb, data, types_tdbtcb,
+- 1, 2, 3, PyUFunc_None,
+- "tdbtcb",
+- "UFunc wrapper for eraTdbtcb",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tdbtcb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tdbtt, data, types_tdbtt,
+- 1, 3, 3, PyUFunc_None,
+- "tdbtt",
+- "UFunc wrapper for eraTdbtt",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tdbtt", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tttai, data, types_tttai,
+- 1, 2, 3, PyUFunc_None,
+- "tttai",
+- "UFunc wrapper for eraTttai",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tttai", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tttcg, data, types_tttcg,
+- 1, 2, 3, PyUFunc_None,
+- "tttcg",
+- "UFunc wrapper for eraTttcg",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tttcg", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tttdb, data, types_tttdb,
+- 1, 3, 3, PyUFunc_None,
+- "tttdb",
+- "UFunc wrapper for eraTttdb",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tttdb", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ttut1, data, types_ttut1,
+- 1, 3, 3, PyUFunc_None,
+- "ttut1",
+- "UFunc wrapper for eraTtut1",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ttut1", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ut1tai, data, types_ut1tai,
+- 1, 3, 3, PyUFunc_None,
+- "ut1tai",
+- "UFunc wrapper for eraUt1tai",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ut1tai", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ut1tt, data, types_ut1tt,
+- 1, 3, 3, PyUFunc_None,
+- "ut1tt",
+- "UFunc wrapper for eraUt1tt",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ut1tt", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ut1utc, data, types_ut1utc,
+- 1, 3, 3, PyUFunc_None,
+- "ut1utc",
+- "UFunc wrapper for eraUt1utc",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ut1utc", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_utctai, data, types_utctai,
+- 1, 2, 3, PyUFunc_None,
+- "utctai",
+- "UFunc wrapper for eraUtctai",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "utctai", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_utcut1, data, types_utcut1,
+- 1, 3, 3, PyUFunc_None,
+- "utcut1",
+- "UFunc wrapper for eraUtcut1",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "utcut1", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ae2hd, data, types_ae2hd,
+- 1, 3, 2, PyUFunc_None,
+- "ae2hd",
+- "UFunc wrapper for eraAe2hd",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ae2hd", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_hd2ae, data, types_hd2ae,
+- 1, 3, 2, PyUFunc_None,
+- "hd2ae",
+- "UFunc wrapper for eraHd2ae",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "hd2ae", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_hd2pa, data, types_hd2pa,
+- 1, 3, 1, PyUFunc_None,
+- "hd2pa",
+- "UFunc wrapper for eraHd2pa",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "hd2pa", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tpors, data, types_tpors,
+- 1, 4, 5, PyUFunc_None,
+- "tpors",
+- "UFunc wrapper for eraTpors",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tpors", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tporv, data, types_tporv,
+- 1, 3, 3, PyUFunc_None,
+- "tporv",
+- "UFunc wrapper for eraTporv",
+- 0, "(),(),(3)->(3),(3),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tporv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tpsts, data, types_tpsts,
+- 1, 4, 2, PyUFunc_None,
+- "tpsts",
+- "UFunc wrapper for eraTpsts",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tpsts", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tpstv, data, types_tpstv,
+- 1, 3, 1, PyUFunc_None,
+- "tpstv",
+- "UFunc wrapper for eraTpstv",
+- 0, "(),(),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tpstv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tpxes, data, types_tpxes,
+- 1, 4, 3, PyUFunc_None,
+- "tpxes",
+- "UFunc wrapper for eraTpxes",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tpxes", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tpxev, data, types_tpxev,
+- 1, 2, 3, PyUFunc_None,
+- "tpxev",
+- "UFunc wrapper for eraTpxev",
+- 0, "(3),(3)->(),(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tpxev", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 2, PyUFunc_None,
+- "a2af",
+- "UFunc wrapper for eraA2af",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_int;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_sign;
+- dtypes[3] = dt_dmsf;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_a2af, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "a2af", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 2, PyUFunc_None,
+- "a2tf",
+- "UFunc wrapper for eraA2tf",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_int;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_sign;
+- dtypes[3] = dt_hmsf;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_a2tf, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "a2tf", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 2, PyUFunc_None,
+- "af2a",
+- "UFunc wrapper for eraAf2a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_sign;
+- dtypes[1] = dt_int;
+- dtypes[2] = dt_int;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_af2a, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "af2a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_anp, data, types_anp,
+- 1, 1, 1, PyUFunc_None,
+- "anp",
+- "UFunc wrapper for eraAnp",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "anp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_anpm, data, types_anpm,
+- 1, 1, 1, PyUFunc_None,
+- "anpm",
+- "UFunc wrapper for eraAnpm",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "anpm", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 2, PyUFunc_None,
+- "d2tf",
+- "UFunc wrapper for eraD2tf",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_int;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_sign;
+- dtypes[3] = dt_hmsf;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_d2tf, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "d2tf", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 2, PyUFunc_None,
+- "tf2a",
+- "UFunc wrapper for eraTf2a",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_sign;
+- dtypes[1] = dt_int;
+- dtypes[2] = dt_int;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_tf2a, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tf2a", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 4, 2, PyUFunc_None,
+- "tf2d",
+- "UFunc wrapper for eraTf2d",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_sign;
+- dtypes[1] = dt_int;
+- dtypes[2] = dt_int;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_int;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_sign,
+- ufunc_loop_tf2d, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tf2d", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rx, data, types_rx,
+- 1, 2, 1, PyUFunc_None,
+- "rx",
+- "UFunc wrapper for eraRx",
+- 0, "(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rx", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ry, data, types_ry,
+- 1, 2, 1, PyUFunc_None,
+- "ry",
+- "UFunc wrapper for eraRy",
+- 0, "(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ry", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rz, data, types_rz,
+- 1, 2, 1, PyUFunc_None,
+- "rz",
+- "UFunc wrapper for eraRz",
+- 0, "(),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rz", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_cp, data, types_cp,
+- 1, 1, 1, PyUFunc_None,
+- "cp",
+- "UFunc wrapper for eraCp",
+- 0, "(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "cp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 1, PyUFunc_None,
+- "cpv",
+- "UFunc wrapper for eraCpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_cpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "cpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_cr, data, types_cr,
+- 1, 1, 1, PyUFunc_None,
+- "cr",
+- "UFunc wrapper for eraCr",
+- 0, "(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "cr", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 1, PyUFunc_None,
+- "p2pv",
+- "UFunc wrapper for eraP2pv",
+- 0, "(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_p2pv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "p2pv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 1, PyUFunc_None,
+- "pv2p",
+- "UFunc wrapper for eraPv2p",
+- 0, "()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pv2p, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pv2p", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ir, data, types_ir,
+- 1, 0, 1, PyUFunc_None,
+- "ir",
+- "UFunc wrapper for eraIr",
+- 0, "->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ir", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_zp, data, types_zp,
+- 1, 0, 1, PyUFunc_None,
+- "zp",
+- "UFunc wrapper for eraZp",
+- 0, "->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "zp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 0, 1, PyUFunc_None,
+- "zpv",
+- "UFunc wrapper for eraZpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_zpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "zpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_zr, data, types_zr,
+- 1, 0, 1, PyUFunc_None,
+- "zr",
+- "UFunc wrapper for eraZr",
+- 0, "->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "zr", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rxr, data, types_rxr,
+- 1, 2, 1, PyUFunc_None,
+- "rxr",
+- "UFunc wrapper for eraRxr",
+- 0, "(3, 3),(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rxr", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_tr, data, types_tr,
+- 1, 1, 1, PyUFunc_None,
+- "tr",
+- "UFunc wrapper for eraTr",
+- 0, "(3, 3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "tr", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rxp, data, types_rxp,
+- 1, 2, 1, PyUFunc_None,
+- "rxp",
+- "UFunc wrapper for eraRxp",
+- 0, "(3, 3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rxp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "rxpv",
+- "UFunc wrapper for eraRxpv",
+- 0, "(3, 3),()->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_rxpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rxpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_trxp, data, types_trxp,
+- 1, 2, 1, PyUFunc_None,
+- "trxp",
+- "UFunc wrapper for eraTrxp",
+- 0, "(3, 3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "trxp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "trxpv",
+- "UFunc wrapper for eraTrxpv",
+- 0, "(3, 3),()->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_trxpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "trxpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rm2v, data, types_rm2v,
+- 1, 1, 1, PyUFunc_None,
+- "rm2v",
+- "UFunc wrapper for eraRm2v",
+- 0, "(3, 3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rm2v", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_rv2m, data, types_rv2m,
+- 1, 1, 1, PyUFunc_None,
+- "rv2m",
+- "UFunc wrapper for eraRv2m",
+- 0, "(3)->(3, 3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "rv2m", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pap, data, types_pap,
+- 1, 2, 1, PyUFunc_None,
+- "pap",
+- "UFunc wrapper for eraPap",
+- 0, "(3),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pap", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pas, data, types_pas,
+- 1, 4, 1, PyUFunc_None,
+- "pas",
+- "UFunc wrapper for eraPas",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pas", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_sepp, data, types_sepp,
+- 1, 2, 1, PyUFunc_None,
+- "sepp",
+- "UFunc wrapper for eraSepp",
+- 0, "(3),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "sepp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_seps, data, types_seps,
+- 1, 4, 1, PyUFunc_None,
+- "seps",
+- "UFunc wrapper for eraSeps",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "seps", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_c2s, data, types_c2s,
+- 1, 1, 2, PyUFunc_None,
+- "c2s",
+- "UFunc wrapper for eraC2s",
+- 0, "(3)->(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "c2s", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_p2s, data, types_p2s,
+- 1, 1, 3, PyUFunc_None,
+- "p2s",
+- "UFunc wrapper for eraP2s",
+- 0, "(3)->(),(),()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "p2s", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 6, PyUFunc_None,
+- "pv2s",
+- "UFunc wrapper for eraPv2s",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pv2s, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pv2s", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s2c, data, types_s2c,
+- 1, 2, 1, PyUFunc_None,
+- "s2c",
+- "UFunc wrapper for eraS2c",
+- 0, "(),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s2c", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_s2p, data, types_s2p,
+- 1, 3, 1, PyUFunc_None,
+- "s2p",
+- "UFunc wrapper for eraS2p",
+- 0, "(),(),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s2p", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 6, 1, PyUFunc_None,
+- "s2pv",
+- "UFunc wrapper for eraS2pv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- dtypes[3] = dt_double;
+- dtypes[4] = dt_double;
+- dtypes[5] = dt_double;
+- dtypes[6] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_s2pv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s2pv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pdp, data, types_pdp,
+- 1, 2, 1, PyUFunc_None,
+- "pdp",
+- "UFunc wrapper for eraPdp",
+- 0, "(3),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pdp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pm, data, types_pm,
+- 1, 1, 1, PyUFunc_None,
+- "pm",
+- "UFunc wrapper for eraPm",
+- 0, "(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pm", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pmp, data, types_pmp,
+- 1, 2, 1, PyUFunc_None,
+- "pmp",
+- "UFunc wrapper for eraPmp",
+- 0, "(3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pmp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pn, data, types_pn,
+- 1, 1, 2, PyUFunc_None,
+- "pn",
+- "UFunc wrapper for eraPn",
+- 0, "(3)->(),(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pn", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ppp, data, types_ppp,
+- 1, 2, 1, PyUFunc_None,
+- "ppp",
+- "UFunc wrapper for eraPpp",
+- 0, "(3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ppp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_ppsp, data, types_ppsp,
+- 1, 3, 1, PyUFunc_None,
+- "ppsp",
+- "UFunc wrapper for eraPpsp",
+- 0, "(3),(),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "ppsp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvdpv",
+- "UFunc wrapper for eraPvdpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pvdpv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvdpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvdpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 2, PyUFunc_None,
+- "pvm",
+- "UFunc wrapper for eraPvm",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvm, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvm", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvmpv",
+- "UFunc wrapper for eraPvmpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvmpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvmpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvppv",
+- "UFunc wrapper for eraPvppv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvppv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvppv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvu",
+- "UFunc wrapper for eraPvu",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvu, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvu", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvup",
+- "UFunc wrapper for eraPvup",
+- 0, "(),()->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvup, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvup", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pvxpv",
+- "UFunc wrapper for eraPvxpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pvxpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pvxpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_pxp, data, types_pxp,
+- 1, 2, 1, PyUFunc_None,
+- "pxp",
+- "UFunc wrapper for eraPxp",
+- 0, "(3),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pxp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 3, 1, PyUFunc_None,
+- "s2xpv",
+- "UFunc wrapper for eraS2xpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- dtypes[3] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_s2xpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "s2xpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- funcs_sxp, data, types_sxp,
+- 1, 2, 1, PyUFunc_None,
+- "sxp",
+- "UFunc wrapper for eraSxp",
+- 0, "(),(3)->(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "sxp", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "sxpv",
+- "UFunc wrapper for eraSxpv",
+- 0, NULL);
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_pv;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_sxpv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "sxpv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 2, 1, PyUFunc_None,
+- "pav2pv",
+- "UFunc wrapper for eraPav2pv",
+- 0, "(3),(3)->()");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_double;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_pv;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pav2pv, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pav2pv", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+- ufunc = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignature(
+- NULL, NULL, NULL,
+- 0, 1, 2, PyUFunc_None,
+- "pv2pav",
+- "UFunc wrapper for eraPv2pav",
+- 0, "()->(3),(3)");
+- if (ufunc == NULL) {
+- goto fail;
+- }
+- dtypes[0] = dt_pv;
+- dtypes[1] = dt_double;
+- dtypes[2] = dt_double;
+- status = PyUFunc_RegisterLoopForDescr(
+- ufunc, dt_pv,
+- ufunc_loop_pv2pav, dtypes, NULL);
+- if(status != 0){
+- Py_DECREF(ufunc);
+- goto fail;
+- }
+- ufunc->type_resolver = &ErfaUFuncTypeResolver;
+- PyDict_SetItemString(d, "pv2pav", (PyObject *)ufunc);
+- Py_DECREF(ufunc);
+-
+- goto decref;
+-
+-fail:
+- Py_XDECREF(m);
+- m = NULL;
+-
+-decref:
+- Py_XDECREF(dt_double);
+- Py_XDECREF(dt_int);
+- Py_XDECREF(dt_pv);
+- Py_XDECREF(dt_pvdpv);
+- Py_XDECREF(dt_ymdf);
+- Py_XDECREF(dt_hmsf);
+- Py_XDECREF(dt_dmsf);
+- Py_XDECREF(dt_sign);
+- Py_XDECREF(dt_type);
+- Py_XDECREF(dt_eraASTROM);
+- Py_XDECREF(dt_eraLDBODY);
+- Py_XDECREF(dt_eraLEAPSECOND);
+- return m;
+-}
+\ No newline at end of file
+Index: astropy-4.1/CHANGES.rst
+===================================================================
+--- astropy-4.1.orig/CHANGES.rst
++++ astropy-4.1/CHANGES.rst
+@@ -1,3 +1,11 @@
++PR10329 -- rebased to 4.1
++=======
++
++- The private ``_erfa`` module has been converted to its own package,
++ ``pyerfa``, which is a required dependency for astropy, and can be imported
++ with ``import erfa``. Importing ``_erfa`` from ``astropy`` will give a
++ deprecation warning. [#10329]
++
+ 4.1 (2020-10-21)
+ ================
+
diff --git a/astropy-pr10545-remove-newline-3d_cd_hdr.patch b/astropy-pr10545-remove-newline-3d_cd_hdr.patch
deleted file mode 100644
index 5199ff9..0000000
--- a/astropy-pr10545-remove-newline-3d_cd_hdr.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From e87d4647f2b152b33ef4c22edc2daf16b1dbc1bc Mon Sep 17 00:00:00 2001
-From: Mihai Cara
-Date: Wed, 8 Jul 2020 13:14:01 -0400
-Subject: [PATCH] Remove newline characters from header file 3d_cd.hdr
-
----
- astropy/wcs/tests/data/3d_cd.hdr | 17 +----------------
- astropy/wcs/tests/test_wcs.py | 9 ++++-----
- 2 files changed, 5 insertions(+), 21 deletions(-)
-
-diff --git a/astropy/wcs/tests/data/3d_cd.hdr b/astropy/wcs/tests/data/3d_cd.hdr
-index be4ce2f1f88..8791e9d35e8 100644
---- a/astropy/wcs/tests/data/3d_cd.hdr
-+++ b/astropy/wcs/tests/data/3d_cd.hdr
-@@ -1,16 +1 @@
--CD1_2 = -3.72E-05
--CD1_3 = 0
--CD1_1 = -4.12E-05
--CUNIT3 = 'nm '
--CUNIT2 = 'deg '
--CTYPE1 = 'RA---TAN'
--NAXIS = 3
--CTYPE3 = 'AWAV '
--CD2_1 = -3.72E-05
--CTYPE2 = 'DEC--TAN'
--CD2_3 = 0
--CD2_2 = 4.12E-05
--CUNIT1 = 'deg '
--CD3_1 = 0
--CD3_2 = 0
--CD3_3 = 0.2
-\ No newline at end of file
-+CD1_2 = -3.72E-05 CD1_3 = 0 CD1_1 = -4.12E-05 CUNIT3 = 'nm ' CUNIT2 = 'deg ' CTYPE1 = 'RA---TAN' NAXIS = 3 CTYPE3 = 'AWAV ' CD2_1 = -3.72E-05 CTYPE2 = 'DEC--TAN' CD2_3 = 0 CD2_2 = 4.12E-05 CUNIT1 = 'deg ' CD3_1 = 0 CD3_2 = 0 CD3_3 = 0.2
-\ No newline at end of file
-diff --git a/astropy/wcs/tests/test_wcs.py b/astropy/wcs/tests/test_wcs.py
-index 509d3e916a3..cd180952458 100644
---- a/astropy/wcs/tests/test_wcs.py
-+++ b/astropy/wcs/tests/test_wcs.py
-@@ -823,11 +823,10 @@ def test_printwcs(capsys):
- captured = capsys.readouterr()
- assert 'WCS Keywords' in captured.out
- h = get_pkg_data_contents('data/3d_cd.hdr', encoding='binary')
-- with pytest.warns(AstropyUserWarning):
-- w = wcs.WCS(h)
-- w.printwcs()
-- captured = capsys.readouterr()
-- assert 'WCS Keywords' in captured.out
-+ w = wcs.WCS(h)
-+ w.printwcs()
-+ captured = capsys.readouterr()
-+ assert 'WCS Keywords' in captured.out
-
-
- def test_invalid_spherical():
diff --git a/python-astropy.changes b/python-astropy.changes
index ba9bbc6..f326143 100644
--- a/python-astropy.changes
+++ b/python-astropy.changes
@@ -1,3 +1,54 @@
+-------------------------------------------------------------------
+Thu Oct 22 09:36:36 UTC 2020 - Benjamin Greiner
+
+- Update to 4.1
+ Astropy 4.1 is a major release that contains bug fixes and new
+ features since the 4.0.x series of releases. In particular, this
+ release includes:
+ * A new SpectralCoord class for representing and transforming
+ spectral quantities
+ * Support for writing Dask arrays to FITS files
+ * Added True Equator Mean Equinox (TEME) frame for satellite two-
+ line ephemeris data
+ * Support for in-place setting of array-valued SkyCoord and frame
+ objects
+ * Change in the definition of equality comparison for coordinate
+ classes
+ * Support use of SkyCoord in table vstack, dstack, and insert_row
+ * Support for table cross-match join with SkyCoord or N-d columns
+ * Support for custom attributes in Table subclasses
+ * Added a new Time subformat unix_tai
+ * Added support for the -TAB convention in FITS WCS
+ * Support for replacing submodels in CompoundModel
+ * Support for units on otherwise unitless models via the
+ Model.coerce_units method.
+ * Support for ASDF serialization of models
+ In addition to these major changes, Astropy v4.0 includes a large
+ number of smaller improvements and bug fixes, which are described
+ in the Full Changelog. By the numbers:
+ * 381 issues have been closed since v4.0
+ * 511 pull requests have been merged since v4.0
+ * 66 distinct people have contributed code to this release, 23 of
+ which are first time contributors to Astropy
+- Drop astropy-pr10545-remove-newline-3d_cd_hdr.patch
+ * merged upstream
+ * gh#astropy/astropy#10545
+- Add astropy-pr10329-unbundle-erfa_4.1.patch
+ * Remove bundled _erfa but use system package pyerfa instead
+ * gh#astropy/astropy#10329
+- enable optional pytest-xdist
+
+-------------------------------------------------------------------
+Thu Oct 15 12:22:54 UTC 2020 - Benjamin Greiner
+
+- Update to 4.0.3
+ * astropy.table
+ Fixed a small bug where initializing an empty `Column`
+ with a structured dtype with a length and a shape
+ failed to give the requested dtype. [#10819]
+ * Fixed installation of the source distribution with
+ pip<19. [#10837, #10852]
+
-------------------------------------------------------------------
Sat Oct 10 20:46:40 UTC 2020 - Benjamin Greiner
diff --git a/python-astropy.spec b/python-astropy.spec
index 1b80cc5..82a0270 100644
--- a/python-astropy.spec
+++ b/python-astropy.spec
@@ -16,90 +16,103 @@
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%global flavor @BUILD_FLAVOR@%{nil}
%if "%{flavor}" == "test"
-%define psuffix -test
%bcond_without test
%else
-%define psuffix %{nil}
%bcond_with test
%endif
+
%define binaries fitsdiff fitsheader fitscheck fitsinfo fits2bitmap samp_hub showtable volint wcslint
+
+%bcond_without systemlibs
+%if %{with systemlibs}
+%define unbundle_libs export ASTROPY_USE_SYSTEM_CFITSIO=1 \
+ export ASTROPY_USE_SYSTEM_EXPAT=1 \
+ export ASTROPY_USE_SYSTEM_WCSLIB=1
+%endif
+
+%{?!python_module:%define python_module() python3-%{**}}
%define skip_python2 1
Name: python-astropy
-Version: 4.0.2
+Version: 4.1
Release: 0
Summary: Community-developed python astronomy tools
License: BSD-3-Clause
URL: https://astropy.org
Source: https://files.pythonhosted.org/packages/source/a/astropy/astropy-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM astropy-pr10545-remove-newline-3d_cd_hdr.patch gh#astropy/astropy#10545 -- clean up newlines after pytest output
-Patch0: astropy-pr10545-remove-newline-3d_cd_hdr.patch
# Mark wcs headers as false positives for devel-file-in-non-devel-package
# These are used by the python files so they must be available.
Source100: python-astropy-rpmlintrc
+# PATCH-FEATURE-UPSTREAM astropy-pr10329-unbundle-erfa_4.1.patch gh#astropy/astropy#10329 -- unbundle _erfa and use pyerfa instead
+Patch0: astropy-pr10329-unbundle-erfa_4.1.patch
+# https://docs.astropy.org/en/v4.1/install.html#requirements
BuildRequires: %{python_module Cython >= 0.21}
-BuildRequires: %{python_module astropy-helpers}
+BuildRequires: %{python_module Jinja2}
BuildRequires: %{python_module devel}
+BuildRequires: %{python_module extension-helpers}
BuildRequires: %{python_module numpy-devel >= 1.16}
-BuildRequires: %{python_module ply}
+BuildRequires: %{python_module setuptools_scm}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: hdf5-devel
-BuildRequires: libxml2-tools
BuildRequires: pkgconfig
BuildRequires: python-rpm-macros
-BuildRequires: pkgconfig(cfitsio)
-BuildRequires: pkgconfig(erfa) >= 1.7.0
-BuildRequires: pkgconfig(expat)
-BuildRequires: pkgconfig(wcslib)
-Requires: hdf5
-Requires: liberfa1 >= 1.7.0
+Requires: python >= 3.6
Requires: python-dbm
-Requires: python-matplotlib >= 2.1
-Requires: python-numpy >= 1.7.0
+Requires: python-numpy >= 1.16.0
Requires(post): update-alternatives
Requires(postun): update-alternatives
Recommends: libxml2-tools
Recommends: python-Bottleneck
-Recommends: python-Jinja2
-Recommends: python-PyYAML
-Recommends: python-asdf >= 2.5
+Recommends: python-PyYAML >= 3.12
+Recommends: python-asdf >= 2.6
Recommends: python-beautifulsoup4
Recommends: python-bleach
Recommends: python-h5py
-Recommends: python-ipython
+Recommends: python-html5lib
Recommends: python-jplephem
Recommends: python-matplotlib >= 2.1
+Recommends: python-mpmath
Recommends: python-pandas
-Recommends: python-scikit-image
Recommends: python-scipy >= 0.18
+Recommends: python-setuptools
+Recommends: python-sortedcontainers
Conflicts: perl-Data-ShowTable
+%if %{with systemlibs}
+BuildRequires: %{python_module pyerfa}
+BuildRequires: pkgconfig(cfitsio)
+BuildRequires: pkgconfig(expat)
+BuildRequires: pkgconfig(wcslib) >= 7
+Requires: python-pyerfa
+%endif
%if %{with test}
# SECTION Optional requirements
BuildRequires: %{python_module Bottleneck}
-BuildRequires: %{python_module Jinja2}
-BuildRequires: %{python_module PyYAML}
-BuildRequires: %{python_module asdf >= 2.5}
+BuildRequires: %{python_module PyYAML >= 3.12}
+BuildRequires: %{python_module asdf >= 2.6}
BuildRequires: %{python_module beautifulsoup4}
BuildRequires: %{python_module bleach}
BuildRequires: %{python_module h5py}
-BuildRequires: %{python_module ipython}
+BuildRequires: %{python_module html5lib}
BuildRequires: %{python_module jplephem}
BuildRequires: %{python_module matplotlib >= 2.1}
+BuildRequires: %{python_module mpmath}
BuildRequires: %{python_module pandas}
-BuildRequires: %{python_module scikit-image}
BuildRequires: %{python_module scipy >= 0.18}
+BuildRequires: %{python_module sortedcontainers}
+BuildRequires: libxml2-tools
# /SECTION
# SECTION test requirements
+# We need the compiled package for testing
BuildRequires: %{python_module astropy = %{version}}
-BuildRequires: %{python_module mpmath}
+BuildRequires: %{python_module ipython}
BuildRequires: %{python_module objgraph}
-BuildRequires: %{python_module pytest >= 3.1}
BuildRequires: %{python_module pytest-astropy}
-BuildRequires: %{python_module pytest-doctestplus >= 0.6}
BuildRequires: %{python_module pytest-mpl}
+BuildRequires: %{python_module pytest-xdist}
+BuildRequires: %{python_module sgp4}
+BuildRequires: %{python_module skyfield}
# /SECTION
%endif
%python_subpackages
@@ -113,61 +126,63 @@ managing them.
%if !%{with test}
%prep
%setup -q -n astropy-%{version}
-%autopatch -p1
+
+%if %{with systemlibs}
+# unbundle liberfa with new package pyerfa
+%patch0 -p1
+rm -rf cextern/erfa
+rm licenses/ERFA.rst
+
+# Make sure bundled libs are not used
+rm -rf cextern/cfitsio
+rm -rf cextern/expat
+rm -rf cextern/wcslib
+rm licenses/EXPAT_LICENSE.rst
+rm licenses/WCSLIB_LICENSE.rst
+
+%endif
# Disable test failure on DeprecationWarnings
sed -i "/enable_deprecations_as_exceptions(/,/)/ d" astropy/conftest.py
-
-# Make sure bundled libs are not used
-rm -rf cextern/expat
-rm -rf cextern/erfa
-rm -rf cextern/cfitsio
-rm -rf cextern/wcslib
-
-echo "[build]" >> setup.cfg
-echo "use_system_libraries=1" >> setup.cfg
+# increase test deadline for slow obs executions (e.g. on s390x)
+echo "
+import hypothesis
+hypothesis.settings.register_profile('obs', deadline=1000)
+" >> astropy/conftest.py
%build
-%python_build --use-system-libraries --offline
+%{?unbundle_libs}
+%python_build
%install
-%python_install --use-system-libraries --offline
+%{?unbundle_libs}
+%python_install
for b in %{binaries}; do
%python_clone -a %{buildroot}%{_bindir}/$b
done
-chmod a-x %{buildroot}%{python_sitearch}/astropy/wcs/tests/data/header_with_time.fits
-# Deduplicating files can generate a RPMLINT warning for pyc mtime
-%{python_expand %fdupes %{buildroot}%{$python_sitearch}
-rm -rf %{buildroot}%{$python_sitearch}/astropy/io/misc/tests/__pycache__/__init__.*.pyc
-rm -rf %{buildroot}%{$python_sitearch}/astropy/io/votable/tests/__pycache__/*_test.*.pyc
-rm -rf %{buildroot}%{$python_sitearch}/astropy/io/votable/tests/__pycache__/__init__.*.pyc
-rm -rf %{buildroot}%{$python_sitearch}/astropy/wcs/tests/__pycache__/__init__.*.pyc
-rm -rf %{buildroot}%{$python_sitearch}/astropy/wcs/tests/extension/__pycache__/__init__.*.pyc
-$python -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/io/misc/tests/
-$python -O -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/io/misc/tests/
-$python -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/io/votable/tests/
-$python -O -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/io/votable/tests/
-$python -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/stats/bls/tests/
-$python -O -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/stats/bls/tests/
-$python -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/wcs/tests/
-$python -O -m compileall -d %{$python_sitearch} %{buildroot}%{$python_sitearch}/astropy/wcs/tests/
-%fdupes %{buildroot}%{$python_sitearch}
-}
+%python_expand %fdupes %{buildroot}%{$python_sitearch}
%endif
%if %{with test}
%check
-# test matrix is ill-conditioned and fails occasionally
-# https://github.com/astropy/astropy/issues/10675
-donttest="compound_fitting_with_units"
%ifarch aarch64
# doctest failure because of precision errors
donttest+=" or bayesian_info_criterion_lsq"
%endif
+testselect_expr="${donttest:+-k \"not (${donttest# or })\"}"
# http://docs.astropy.org/en/latest/development/testguide.html#running-tests
# running pytest directly would require building the extensions inplace
-%python_exec -B -c "import astropy, sys; sys.exit(astropy.test(args=\"-v -k \\\"not ($donttest)\\\"\"))"
+%python_exec -B -c "
+import sys, astropy
+pytestargs = ('-v '
+ '-n auto ' # pytest-xdist
+ '-p no:cacheprovider '
+ '--hypothesis-profile=obs '
+ '$testselect_expr')
+returncode = astropy.test(args=pytestargs)
+sys.exit(returncode)
+"
%endif
%if !%{with test}
@@ -179,10 +194,10 @@ donttest="compound_fitting_with_units"
%files %{python_files}
%doc CHANGES.rst README.rst
-%license licenses/*
+%license LICENSE.rst licenses/*
%{expand:%(for b in %{binaries}; do echo "%%python_alternative %%{_bindir}/$b"; done)}
%{python_sitearch}/astropy/
-%{python_sitearch}/astropy-%{version}-py*.egg-info
+%{python_sitearch}/astropy-%{version}*-info
%endif
%changelog